spring配置<context:annotation-config>与<context:component-scan>
内容来自: http://blog.csdn.net/baple/article/details/16864835
annotation-config用于激活spring容器中bean上的注解,是一个注解处理工具。这些bean可以是通过xml配置的,也可以是注解的
component-scan可以扫描指定package下的@Component注解(含子注解@Controller,@Service,@Reposity等),并将相应的bean在spring容器中注册,同时component-scan还具有annotation-config的功能,即处理spring窗口中bean上的注解。
如果同时配置了<context:component-scan>和<context:annotation-config/>,那么后者会被忽略。
一、不使用注解的方式。
有如下ABC三个类,A类中包含了B和C的一个实例。
package com.xxx; public class B { public B() { System.out.println("creating bean B: " + this); } } package com.xxx; public class C { public C() { System.out.println("creating bean C: " + this); } } package com.yyy; import com.xxx.B; import com.xxx.C; public class A { private B bbb; private C ccc; public A() { System.out.println("creating bean A: " + this); } public void setBbb(B bbb) { System.out.println("setting A.bbb with " + bbb); this.bbb = bbb; } public void setCcc(C ccc) { System.out.println("setting A.ccc with " + ccc); this.ccc = ccc; } }
在applicationContext.xml中加入下面的配置 :
<bean id="bBean"class="com.xxx.B"/> <bean id="cBean"class="com.xxx.C"/> <bean id="aBean"class="com.yyy.A"> <property name="bbb" ref="bBean"/> <property name="ccc" ref="cBean"/> </bean>
加载applicationContext.xml配置文件,将得到下面的结果:
creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6
这完全符合预期。
二、annotation-config的作用
我们使用autowire注解的方式将对象B和C注入到A中:
package com.yyy; import org.springframework.beans.factory.annotation.Autowired; import com.xxx.B; import com.xxx.C; public class A { private B bbb; private C ccc; public A() { System.out.println("creating bean A: " + this); } @Autowired public void setBbb(B bbb) { System.out.println("setting A.bbb with " + bbb); this.bbb = bbb; } @Autowired public void setCcc(C ccc) { System.out.println("setting A.ccc with " + ccc); this.ccc = ccc; } }
然后,applicationContext.xml配置文件简化为下面的样子
<bean id="bBean"class="com.xxx.B"/> <bean id="cBean"class="com.xxx.C"/> <bean id="aBean"class="com.yyy.A"/>
加载applicationContext.xml配置文件之后,将得到下面的结果:
creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf
显然对象B和C没有成功注入到A中,因为注解本身并不能够做任何事情,它们只是最基本的组成部分,它们需要别的工具来处理。
在这里,这个工具就是<context:annotation-config>
将applicationContext.xml改为:
<context:annotation-config /> <bean id="bBean"class="com.xxx.B"/> <bean id="cBean"class="com.xxx.C"/> <bean id="aBean"class="com.yyy.A"/>
这次输出将是正确的。
三、component-scan的作用
现在将bean的注解及装配完全改为注解方式
package com.xxx; import org.springframework.stereotype.Component; @Component public class B { public B() { System.out.println("creating bean B: " + this); } } package com.xxx; import org.springframework.stereotype.Component; @Component public class C { public C() { System.out.println("creating bean C: " + this); } } package com.yyy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.xxx.B; import com.xxx.C; @Component public class A { private B bbb; private C ccc; public A() { System.out.println("creating bean A: " + this); } @Autowired public void setBbb(B bbb) { System.out.println("setting A.bbb with " + bbb); this.bbb = bbb; } @Autowired public void setCcc(C ccc) { System.out.println("setting A.ccc with " + ccc); this.ccc = ccc; } }
applicationContext.xml配置文件只保留一行:
<context:annotation-config />
这样加载applicationContext.xml配置文件之后,没有任何输出
因为annotation-config只能在spring容器中的bean上起作用(处理spring容器中的bean上的注解)
上面ABC三个类根本都没有在spring容器中注册。
将applicationContext.xml改为:
<context:component-scan base-package="com.xxx,com.yyy"/>
注意,1.是改为而不是添加component-scan配置,虽然添加也可以.
2.指定需要扫描的包,而A和BC在不同的包内,都要配置.
结果又正确了。