1. 程式人生 > >Spring和SpringMVC自動掃描註解類的衝突問題

Spring和SpringMVC自動掃描註解類的衝突問題

Spring MVC專案中通常會有二個配置檔案,spring-servlet.xml和applicationContext.xml二個配置檔案,通常會出現以下幾個配置:

1. <context:annotation-config />

它的作用是隱式地向 Spring 容器註冊  
- AutowiredAnnotationBeanPostProcessor、
- CommonAnnotationBeanPostProcessor、
- PersistenceAnnotationBeanPostProcessor、
- RequiredAnnotationBeanPostProcessor 這4個BeanPostProcessor。

其作用是如果你想在程式中使用註解,就必須先註冊該註解對應的類,如下圖所示:

依賴的類 註解
CommonAnnotationBeanPostProcessor @Resource 、@PostConstruct、@PreDestroy
PersistenceAnnotationBeanPostProcessor @PersistenceContext
AutowiredAnnotationBeanPostProcessor @Autowired
RequiredAnnotationBeanPostProcessor @Required

當然也可以自己進行註冊:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>  
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

2. <context:component-scan base-package="com.*" >

<context:component-scan/> 配置項不但啟用了對類包進行掃描以實施註釋驅動 Bean 定義的功能,同時還啟用了註釋驅動自動注入的功能(即還隱式地在內部註冊了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此當使用 <context:component-scan/> 後,就可以將 <context:annotation-config/> 移除了。

在這裡有一個比較有意思的問題,就是掃描是否需要在二個配置檔案都配置一遍,我做了這麼幾種測試:

(1)只在applicationContext.xml中配置如下

<context:component-scan base-package="com.login" />

啟動正常,但是任何請求都不會被攔截,簡而言之就是@Controller失效

(2)只在spring-servlet.xml中配置上述配置

啟動正常,請求也正常,但是事物失效,也就是不能進行回滾

(3)在applicationContext.xml和spring-servlet.xml中都配置上述資訊

啟動正常,請求正常,也是事物失效,不能進行回滾

(4)在applicationContext.xml中配置如下

<context:component-scan base-package="com.login" />

在spring-servlet.xml中配置如下

<context:component-scan base-package="com.sohu.login.web" />

此時啟動正常,請求正常,事物也正常了。

結論:在spring-servlet.xml中只需要掃描所有帶@Controller註解的類,在applicationContext中可以掃描所有其他帶有註解的類(也可以過濾掉帶@Controller註解的類)。

3. <mvc:annotation-driven />

它會自動註冊DefaultAnnotationHandlerMapping 與AnnotationMethodHandlerAdapter