首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 擴充 MultiActionController 實作自動 URL 映射(下)

     編輯:Java 相關知識

目標

實作 MultiMethodControllerUrlHandlerMapping,自動掃描 Spring 容器中所有 MultiMethodController 型別的 Bean,讀取其 urlMethodMappings 屬性,建立「URL → Controller」對應表,免除手工在 SimpleUrlHandlerMapping 逐一配置。

核心實作

public class MultiMethodControllerUrlHandlerMapping
    extends AbstractUrlHandlerMapping {

    private Map<String, Object> urlMap = new HashMap<>();

    @Override
    protected void initApplicationContext() throws BeansException {
        initialUrlMap();
    }

    private void initialUrlMap() throws BeansException {
        // 1. 取得容器中所有 MultiMethodController 及其子類 Bean
        Map<String, MultiMethodController> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(
                getWebApplicationContext(),
                MultiMethodController.class, true, false);

        if (!matchingBeans.isEmpty()) {
            for (MultiMethodController controller : matchingBeans.values()) {
                Properties urlProps = controller.getUrlMethodMappings();
                for (String url : urlProps.stringPropertyNames()) {
                    urlMap.put(url, controller);  // URL → Controller 實例
                }
            }
        }
    }

    @Override
    protected Object getHandlerInternal(HttpServletRequest request)
        throws Exception {
        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        Object handler = urlMap.get(lookupPath);
        if (handler != null) {
            return handler;
        }
        return super.getHandlerInternal(request); // fallback
    }
}

關鍵點解析

  1. 繼承 AbstractUrlHandlerMapping:自動擁有 WebApplicationContext 存取能力。
  2. BeanFactoryUtils.beansOfTypeIncludingAncestors():遞迴搜尋父容器,確保跨模組 Controller 皆被掃描。
  3. MultiMethodController.getUrlMethodMappings():約定 Controller 需暴露此屬性(Properties 型別),Key 為 URL,Value 為方法名。
  4. 覆寫 getHandlerInternal():依請求路徑直接從 urlMap 查找 Controller,效能 O(1)。

Spring 配置啟用

<bean class="com.yourpkg.MultiMethodControllerUrlHandlerMapping">
  <property name="order" value="0"/> <!-- 優先順序最高 -->
</bean>

Controller 端寫法

public class SampleMultiMethodController extends MultiActionController
    implements MultiMethodController {

    private Properties urlMethodMappings = new Properties();
    // setter/getter 略

    public ModelAndView listUser(HttpServletRequest req, HttpServletResponse res) { ... }
    public ModelAndView editUser(HttpServletRequest req, HttpServletResponse res) { ... }
    public ModelAndView saveUser(HttpServletRequest req, HttpServletResponse res, UserDTO cmd) { ... }
    public ModelAndView deleteUser(HttpServletRequest req, HttpServletResponse res) { ... }
}

在 Bean 定義中設定 urlMethodMappings:

<bean id="sampleMultiMethodController"
  class="com.prs.application.ehld.sample.web.controller.SampleMultiMethodController">
  <property name="urlMethodMappings">
    <props>
      <prop key="/ehld.sample.getuserinfolist.do">listUser</prop>
      <prop key="/ehld.sample.edituserinfo.do">editUser</prop>
      <prop key="/ehld.sample.saveuserinfo.do">saveUser</prop>
      <prop key="/ehld.sample.deleteuserinfo.do">deleteUser</prop>
    </props>
  </property>
  <property name="sampleAction" ref="sampleAction"/>
</bean>

優缺點總結

優點缺點
零配置 URL Mapping,Controller 自描述需自訂介面 MultiMethodController,侵入性稍高
新增方法只需在 Controller 內加映射,無須動 XMLURL 衝突檢測需自行實作(如兩 Controller 映射同一 URL)
符合「高內聚」:相關操作集中在同一 ControllerSpring 3+ 建議改用 @Controller + @RequestMapping,此方案屬歷史遺產

結語

透過自訂 UrlHandlerMapping 掃描 Controller 內部映射屬性,可大幅簡化 Spring MVC 早期版本的配置複雜度。現代專案請直接使用註解式開發,但此機制對理解 Spring MVC 請求分派原理極具參考價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved