日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

context:component-scan/和mvc:annotation-driven/的区别

發(fā)布時間:2024/4/17 c/c++ 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 context:component-scan/和mvc:annotation-driven/的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://www.iteye.com/problems/66133

<mvc:annotation-driven/>相當(dāng)于注冊了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter兩個bean,配置一些messageconverter。即解決了@Controller注解的使用前提配置。

<context:annotation-config/>是對包進(jìn)行掃描,實(shí)現(xiàn)注釋驅(qū)動Bean定義,同時將bean自動注入容器中使用。即解決了@Controller標(biāo)識的類的bean的注入和使用。

一開始我在寫配置的時候,只寫了<context:component-scan/>,并沒有使用<mvc:annotation-driven/>,servlet攔截*.do,.do請求可以被正確捕捉和處理。代碼如下
mvc-servlet.xml

Java代碼 ?
  • <context:component-scan?base-package="com"></context:component-scan>??
  • <context:component-scan base-package="com"></context:component-scan>



    web.xml

    Java代碼 ?
  • <servlet> ??
  • ????<servlet-name>mvc</servlet-name> ??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> ??
  • ????<load-on-startup>1</load-on-startup> ??
  • </servlet> ??
  • <servlet-mapping> ??
  • ????<servlet-name>mvc</servlet-name> ??
  • ????<url-pattern>*.do</url-pattern> ??
  • </servlet-mapping>??
  • <servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup> </servlet> <servlet-mapping><servlet-name>mvc</servlet-name><url-pattern>*.do</url-pattern> </servlet-mapping>




    后來為了解決靜態(tài)資源訪問的問題,servlet改成了攔截所有請求,即/,并添加了默認(rèn)的servlet,這時候*.do請求不能被控制器捕捉了,頁面錯誤為404。直到添加了<mvc:annotation-driven/>之后,.do請求才又能被正確捕捉和處理。代碼如下
    mvc-servlet.xml

    Java代碼 ?
  • <context:component-scan?base-package="com"></context:component-scan> ??
  • <mvc:annotation-driven/> ??
  • <mvc:resources?mapping="/styles/**"?location="/WEB-INF/resource/styles/"/> ??
  • <mvc:default-servlet-handler/>??
  • <context:component-scan base-package="com"></context:component-scan> <mvc:annotation-driven/> <mvc:resources mapping="/styles/**" location="/WEB-INF/resource/styles/"/> <mvc:default-servlet-handler/>



    web.xml

    Java代碼 ?
  • <servlet> ??
  • ????<servlet-name>mvc</servlet-name> ??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> ??
  • ????<load-on-startup>1</load-on-startup> ??
  • </servlet> ??
  • <servlet-mapping> ??
  • ????<servlet-name>mvc</servlet-name> ??
  • ????<url-pattern>/</url-pattern> ??
  • </servlet-mapping>??
  • <servlet><servlet-name>mvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup> </servlet> <servlet-mapping><servlet-name>mvc</servlet-name><url-pattern>/</url-pattern> </servlet-mapping>



    是什么原因造成這種區(qū)別的呢?為什么一開始沒用<mvc:annotation-driven/>的時候可以,添加了默認(rèn)servlet之后就不行了呢?

    ?

    最后的配置如果沒有<mvc:annotation-driven/>,那么所有的Controller可能就沒有解析,所有當(dāng)有請求時候都沒有匹配的處理請求類,就都去<mvc:default-servlet-handler/>即default servlet處理了。添加上<mvc:annotation-driven/>后,相應(yīng)的do請求被Controller處理,而靜態(tài)資源因為沒有相應(yīng)的Controller就會被default servlet處理。總之沒有相應(yīng)的Controller就會被default servlet處理就ok了。

    ?

    =====http://www.cnblogs.com/shines77/p/3315445.html

    mvc:annotation-driven是一種簡寫的配置方式,那么mvc:annotation-driven到底做了哪些工作呢?如何替換掉mvc:annotation-driven呢?

    <mvc:annotation- driven/>在初始化的時候會自動創(chuàng)建兩個對 象,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter 和 org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter, 我們?nèi)绻氩皇褂?lt;mvc:annotation-driven/>這種簡寫方式,將其替換掉的話,就必須自己手動去配置這兩個bean對 象。下面是這兩個對象的配置方法,和詳細(xì)的注視說明。

    ?

    ==========http://jinnianshilongnian.iteye.com/blog/1762632

    context:component-scan掃描使用上的容易忽略的use-default-filters

    ?

    問題

    如下方式可以成功掃描到@Controller注解的Bean,不會掃描@Service/@Repository的Bean。正確

    ?

    Java代碼 ?
  • ?<context:component-scan?base-package="org.bdp.system.test.controller">? ??
  • ?????<context:include-filter?type="annotation"?expression="org.springframework.stereotype.Controller"/>? ??
  • </context:component-scan>??
  • <context:component-scan base-package="org.bdp.system.test.controller"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

    ??

    但是如下方式,不僅僅掃描@Controller,還掃描@Service/@Repository的Bean,可能造成一些問題

    ?

    Java代碼 ?
  • ?<context:component-scan?base-package="org.bdp">? ??
  • ?????<context:include-filter?type="annotation"?expression="org.springframework.stereotype.Controller"/>? ??
  • </context:component-scan>??
  • <context:component-scan base-package="org.bdp"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

    ?

    這個尤其在springmvc+spring+hibernate等集成時最容易出問題的地,最典型的錯誤就是:

    事務(wù)不起作用

    ?

    這是什么問題呢?

    分析

    1、<context:component-scan>會交給org.springframework.context.config.ContextNamespaceHandler處理;

    ?

    Java代碼 ?
  • registerBeanDefinitionParser("component-scan",?new?ComponentScanBeanDefinitionParser());??
  • registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());

    ?

    2、ComponentScanBeanDefinitionParser會讀取配置文件信息并組裝成org.springframework.context.annotation.ClassPathBeanDefinitionScanner進(jìn)行處理;

    3、如果沒有配置<context:component-scan>的use-default-filters屬性,則默認(rèn)為true,在創(chuàng)建ClassPathBeanDefinitionScanner時會根據(jù)use-default-filters是否為true來調(diào)用如下代碼:

    ?

    Java代碼 ?
  • ??protected?void?registerDefaultFilters()?{ ??
  • this.includeFilters.add(new?AnnotationTypeFilter(Component.class)); ??
  • ClassLoader?cl?=?ClassPathScanningCandidateComponentProvider.class.getClassLoader(); ??
  • try?{ ??
  • ????this.includeFilters.add(new?AnnotationTypeFilter( ??
  • ????????????((Class<??extends?Annotation>)?cl.loadClass("javax.annotation.ManagedBean")),?false)); ??
  • ????logger.info("JSR-250?'javax.annotation.ManagedBean'?found?and?supported?for?component?scanning"); ??
  • } ??
  • catch?(ClassNotFoundException?ex)?{ ??
  • ????//?JSR-250?1.1?API?(as?included?in?Java?EE?6)?not?available?-?simply?skip. ??
  • } ??
  • try?{ ??
  • ????this.includeFilters.add(new?AnnotationTypeFilter( ??
  • ????????????((Class<??extends?Annotation>)?cl.loadClass("javax.inject.Named")),?false)); ??
  • ????logger.info("JSR-330?'javax.inject.Named'?annotation?found?and?supported?for?component?scanning"); ??
  • } ??
  • catch?(ClassNotFoundException?ex)?{ ??
  • ????//?JSR-330?API?not?available?-?simply?skip. ??
  • } ??
  • protected void registerDefaultFilters() {this.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false));logger.info("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false));logger.info("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}

    ?

    ?

    可以看到默認(rèn)ClassPathBeanDefinitionScanner會自動注冊對@Component、@ManagedBean、@Named注解的Bean進(jìn)行掃描。如果細(xì)心,到此我們就找到問題根源了。

    ?

    ?

    4、在進(jìn)行掃描時會通過include-filter/exclude-filter來判斷你的Bean類是否是合法的:

    ?

    Java代碼 ?
  • protected?boolean?isCandidateComponent(MetadataReader?metadataReader)?throws?IOException?{ ??
  • ????for?(TypeFilter?tf?:?this.excludeFilters)?{ ??
  • ????????if?(tf.match(metadataReader,?this.metadataReaderFactory))?{ ??
  • ????????????return?false; ??
  • ????????} ??
  • ????} ??
  • ????for?(TypeFilter?tf?:?this.includeFilters)?{ ??
  • ????????if?(tf.match(metadataReader,?this.metadataReaderFactory))?{ ??
  • ????????????AnnotationMetadata?metadata?=?metadataReader.getAnnotationMetadata(); ??
  • ????????????if?(!metadata.isAnnotated(Profile.class.getName()))?{ ??
  • ????????????????return?true; ??
  • ????????????} ??
  • ????????????AnnotationAttributes?profile?=?MetadataUtils.attributesFor(metadata,?Profile.class); ??
  • ????????????return?this.environment.acceptsProfiles(profile.getStringArray("value")); ??
  • ????????} ??
  • ????} ??
  • ????return?false; ??
  • }??
  • protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {for (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, this.metadataReaderFactory)) {return false;}}for (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, this.metadataReaderFactory)) {AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();if (!metadata.isAnnotated(Profile.class.getName())) {return true;}AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);return this.environment.acceptsProfiles(profile.getStringArray("value"));}}return false;}

    ?

    首先通過exclude-filter 進(jìn)行黑名單過濾;

    然后通過include-filter?進(jìn)行白名單過濾;

    否則默認(rèn)排除。

    ?

    結(jié)論

    Java代碼 ?
  • <context:component-scan?base-package="org.bdp">? ??
  • ?????<context:include-filter?type="annotation"?expression="org.springframework.stereotype.Controller"/>? ??
  • </context:component-scan>??
  • <context:component-scan base-package="org.bdp"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

    ?

    為什么這段代碼不僅僅掃描@Controller注解的Bean,而且還掃描了@Component的子注解@Service、@Reposity。因為use-default-filters默認(rèn)為true。所以如果不需要默認(rèn)的,則use-default-filters=“false”禁用掉。

    ?

    ?

    請參考

    《SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結(jié)》?

    《第三章 DispatcherServlet詳解 ——跟開濤學(xué)SpringMVC》中的ContextLoaderListener初始化的上下文和DispatcherServlet初始化的上下文關(guān)系。

    ?

    如果在springmvc配置文件,不使用cn.javass.demo.web.controller前綴,而是使用cn.javass.demo,則service、dao層的bean可能也重新加載了,但事務(wù)的AOP代理沒有配置在springmvc配置文件中,從而造成新加載的bean覆蓋了老的bean,造成事務(wù)失效。只要使用use-default-filters=“false”禁用掉默認(rèn)的行為就可以了。

    ?

    問題不難,spring使用上的問題。總結(jié)一下方便再遇到類似問題的朋友參考。

    ?

    ?

    ========================

    http://my.oschina.net/u/1012289/blog/129298

    自己看了官方文檔,也到網(wǎng)上查了下,目前理解如下: ?
    <context:component-scan/>和<mvc:annotation-driven/>:
    <mvc:annotation-driven/>相當(dāng)于注冊了DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter兩個bean,配置一些messageconverter。即解決了@Controller注解的使用前提配置。?

    <context:annotation-config/>是對包進(jìn)行掃描,實(shí)現(xiàn)注釋驅(qū)動Bean定義,同時將bean自動注入容器中使用。即解決了@Controller標(biāo)識的類的bean的注入和使用。?

    一開始我在寫配置的時候,只寫了<context:component-scan/>,并沒有使用<mvc:annotation-driven/>,servlet攔截*.do,.do請求可以被正確捕捉和處理。代碼如下?
    mvc-servlet.xml?

    Java代碼??
  • <context:component-scan?base-package="com"></context:component-scan>??


  • web.xml?

    Java代碼??
  • <servlet>??
  • ????<servlet-name>mvc</servlet-name>??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????<load-on-startup>1</load-on-startup>??
  • </servlet>??
  • <servlet-mapping>??
  • ????<servlet-name>mvc</servlet-name>??
  • ????<url-pattern>*.do</url-pattern>??
  • </servlet-mapping>??



  • 后來為了解決靜態(tài)資源訪問的問題,servlet改成了攔截所有請求,即/,并添加了默認(rèn)的servlet,這時候*.do請求不能被控制器捕捉了,頁面錯誤為404。直到添加了<mvc:annotation-driven/>之后,.do請求才又能被正確捕捉和處理。代碼如下?
    mvc-servlet.xml?

    Java代碼??
  • <context:component-scan?base-package="com"></context:component-scan>??
  • <mvc:annotation-driven/>??
  • <mvc:resources?mapping="/styles/**"?location="/WEB-INF/resource/styles/"/>??
  • <mvc:default-servlet-handler/>??


  • web.xml?

    Java代碼??
  • <servlet>??
  • ????<servlet-name>mvc</servlet-name>??
  • ????<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>??
  • ????<load-on-startup>1</load-on-startup>??
  • </servlet>??
  • <servlet-mapping>??
  • ????<servlet-name>mvc</servlet-name>??
  • ????<url-pattern>/</url-pattern>??
  • </servlet-mapping>??


  • 是什么原因造成這種區(qū)別的呢?為什么一開始沒用<mvc:annotation-driven/>的時候可以,添加了默認(rèn)servlet之后就不行了呢?

    <context:annotation-config/>和<context:component-scan/>:

    在基于主機(jī)方式配置Spring的配置文件中,你可能會見到<context:annotation-config/>這樣一條配置,他的作用是式地向?Spring?容器注冊

    AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor

    PersistenceAnnotationBeanPostProcessor?以及?RequiredAnnotationBeanPostProcessor??4?BeanPostProcessor

    注冊這4?BeanPostProcessor的作用,就是為了你的系統(tǒng)能夠識別相應(yīng)的注解。

    例如:

    如果你想使用@Autowired注解,那么就必須事先在?Spring?容器中聲明?AutowiredAnnotationBeanPostProcessor Bean。傳統(tǒng)聲明方式如下

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

    如果想使用@ Resource?@ PostConstruct@ PreDestroy等注解就必須聲明CommonAnnotationBeanPostProcessor

    如果想使用@PersistenceContext注解,就必須聲明PersistenceAnnotationBeanPostProcessorBean

    如果想使用?@Required的注解,就必須聲明RequiredAnnotationBeanPostProcessorBean。同樣,傳統(tǒng)的聲明方式如下:

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

    一般來說,這些注解我們還是比較常用,尤其是Antowired的注解,在自動注入的時候更是經(jīng)常使用,所以如果總是需要按照傳統(tǒng)的方式一條一條配置顯得有些繁瑣和沒有必要,于是spring給我們提供<context:annotation-config/>的簡化配置方式,自動幫你完成聲明。

    ???不過,呵呵,我們使用注解一般都會配置掃描包路徑選項

    <context:component-scan?base-package=”XX.XX”/>?

    ????該配置項其實(shí)也包含了自動注入上述processor的功能,因此當(dāng)使用?<context:component-scan/>?后,就可以將?<context:annotation-config/>?移除了。

    ?

    ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的context:component-scan/和mvc:annotation-driven/的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。