我正在学习Spring 3,我似乎没有掌握<context:annotation-config>和<context:component-scan>背后的功能。

从我读到的内容来看,它们似乎处理不同的注释(@Required, @Autowired等vs @Component, @Repository, @Service等),但从我读到的内容来看,它们注册了相同的bean后处理器类。

更让我困惑的是,在<context:component-scan>上有一个annotation-config属性。

有人能解释一下这些标签吗?什么是相似的,什么是不同的,是一个被另一个取代,它们互相完善,我需要其中一个吗,还是两个?


当前回答

<context:component-scan /> implicitly enables <context:annotation-config/>

try with <context:component-scan base-package="…" annotation-config="false"/>,在你的配置中@Service, @Repository, @Component工作正常,但是@Autowired,@Resource和@Inject不工作。

这意味着AutowiredAnnotationBeanPostProcessor将不会被启用,Spring容器将不会处理自动装配注释。

其他回答

<context:component-scan/>自定义标记除了主要负责扫描java包和从类路径注册bean定义外,还注册了与by所做的相同的bean定义集。

如果出于某种原因要避免这种默认bean定义的注册,方法是在component-scan中指定一个额外的“annotation-config”属性,如下所示:

<context:component-scan basePackages="" annotation-config="false"/>

参考: http://www.java-allandsundry.com/2012/12/contextcomponent-scan-contextannotation.html

我发现了一个很好的总结,说明哪些注释被哪些声明拾取。通过研究它,你会发现<context:component-scan/>识别了<context:annotation-config/>识别的注释的超集,即:

@组件,@服务,@存储库,@控制器,@端点 @Configuration, @Bean, @Lazy, @Scope, @Order, @Primary, @Profile, @DependsOn, @Import, @ImportResource

正如您所看到的,<context:component-scan/>逻辑上扩展了<context:annotation-config/>,具有CLASSPATH组件扫描和Java @Configuration特性。

<context:component-scan /> implicitly enables <context:annotation-config/>

try with <context:component-scan base-package="…" annotation-config="false"/>,在你的配置中@Service, @Repository, @Component工作正常,但是@Autowired,@Resource和@Inject不工作。

这意味着AutowiredAnnotationBeanPostProcessor将不会被启用,Spring容器将不会处理自动装配注释。

<context:annotation-config/> <!-- is used to activate the annotation for beans -->
<context:component-scan base-package="x.y.MyClass" /> <!-- is for the Spring IOC container to look for the beans in the base package. -->

要注意的另一个重要点是context:component-scan隐式调用context:annotation-config来激活bean上的注释。如果你不想让context:component-scan隐式地为你激活注释,你可以继续将context:component-scan的annotation-config元素设置为false。

总结:

<context:annotation-config/> <!-- activates the annotations --> 
<context:component-scan base-package="x.y.MyClass" /> <!-- activates the annotations + register the beans by looking inside the base-package -->

两者之间的区别真的很简单!

<context:annotation-config /> 

允许您使用仅限于连接bean的属性和构造函数的注释!

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

启用<context:annotation-config />可以做的所有事情,添加使用原型,例如..@组件,@服务,@存储库。因此,您可以连接整个bean,而不仅仅局限于构造函数或属性!