<context:annotation-config>用于激活已经在应用程序上下文中注册的bean中的注释(无论它们是使用XML定义还是通过包扫描定义的)。
<context:component-scan>不仅可以执行
<context:annotation-config>*** 作,
<context:component-scan>还可以扫描软件包以在应用程序上下文中查找并注册bean。
我将使用一些示例来显示差异/相似之处。
让我们用型的三种豆基本设置开始
A,
B并且
C,与
B和
C被注入
A。
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; }}
使用以下XML配置:
<bean id="bBean" /><bean id="cBean" /><bean id="aBean" > <property name="bbb" ref="bBean" /> <property name="ccc" ref="cBean" /></bean>
加载上下文会产生以下输出:
creating bean B: com.xxx.B@c2ff5creating bean C: com.xxx.C@1e8a1f6creating bean A: com.yyy.A@1e152c5setting A.bbb with com.xxx.B@c2ff5setting A.ccc with com.xxx.C@1e8a1f6
好的,这是预期的输出。但这是“旧风格”的spring。现在我们有了注释,因此让我们使用它们来简化XML。
首先,让我们自动连接
bean的
bbb和
ccc属性,
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; }}
这使我可以从XML中删除以下行:
<property name="bbb" ref="bBean" /><property name="ccc" ref="cBean" />
我的XML现在简化为:
<bean id="bBean" /><bean id="cBean" /><bean id="aBean" />
当我加载上下文时,我得到以下输出:
creating bean B: com.xxx.B@5e5a50creating bean C: com.xxx.C@54a328creating bean A: com.yyy.A@a3d4cf
好,这是错误的!发生了什么?为什么我的房屋不自动接线?
好吧,注解是一个不错的功能,但就其本身而言,它们什么也没做。他们只是注释东西。你需要一个处理工具来查找批注并对其进行处理。
<context:annotation-config>进行营救。这将激活对在定义自身的相同应用程序上下文中定义的bean上发现的注释的 *** 作。
如果我将XML更改为此:
<context:annotation-config /><bean id="bBean" /><bean id="cBean" /><bean id="aBean" />
当我加载应用程序上下文时,我得到正确的结果:
creating bean B: com.xxx.B@15663a2creating bean C: com.xxx.C@cd5f8bcreating bean A: com.yyy.A@157aa53setting A.bbb with com.xxx.B@15663a2setting A.ccc with com.xxx.C@cd5f8b
好的,这很好,但是我从XML中删除了两行并添加了一行。那不是很大的区别。带有注释的想法是应该删除XML。
因此,让我们删除XML定义并将其全部替换为注释:
package com.xxx;import org.springframework.stereotype.Component;@Componentpublic class B { public B() { System.out.println("creating bean B: " + this); }}package com.xxx;import org.springframework.stereotype.Component;@Componentpublic 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;@Componentpublic 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; }}
在XML中,我们仅保留以下内容:
<context:annotation-config />
我们加载上下文,结果是……什么都没有。没有创建bean,也没有自动装配bean。没有!
这是因为,正如我在第一段中所述,这
<context:annotation-config />仅适用于在应用程序上下文中注册的bean。因为我删除了这三个bean的XML配置,所以没有创建bean,
<context:annotation-config />也没有要处理的“目标”。
但这不会成为一个问题
<context:component-scan>,可以扫描软件包以查找“目标”。让我们将XML配置的内容更改为以下条目:
<context:component-scan base-package="com.xxx" />
当我加载上下文时,我得到以下输出:
creating bean B: com.xxx.B@1be0f0acreating bean C: com.xxx.C@80d1ff
嗯…有些东西丢失了。为什么?
如果你在班closelly看,类A有包com.yyy,但我已经在指定
<context:component-scan>使用的软件包com.xxx所以这完全错过了我的A班,只有拿起B和C它们的com.xxx软件包。
为了解决这个问题,我还添加了另一个软件包:
<context:component-scan base-package="com.xxx,com.yyy" />
现在我们得到了预期的结果:
creating bean B: com.xxx.B@cd5f8bcreating bean C: com.xxx.C@15ac3c9creating bean A: com.yyy.A@ec4a87setting A.bbb with com.xxx.B@cd5f8bsetting A.ccc with com.xxx.C@15ac3c9
就是这样!现在你不再有XML定义,而有了注释。
作为最后一个示例,保留带注释的类A,B并将C以下内容添加到XML中,加载上下文后会得到什么?
<context:component-scan base-package="com.xxx" /><bean id="aBean" />
我们仍然得到正确的结果:
creating bean B: com.xxx.B@157aa53creating bean C: com.xxx.C@ec4a87creating bean A: com.yyy.A@1d64c37setting A.bbb with com.xxx.B@157aa53setting A.ccc with com.xxx.C@ec4a87
即使A不是通过扫描获得用于类的Bean ,处理工具仍将应用于
<context:component-scan>在应用程序上下文中注册的所有Bean,即使A是已在XML中手动注册的。
但是,如果我们具有以下XML,会不会得到重复的bean,因为我们同时指定了
<context:annotation-config />和
<context:component-scan>?
<context:annotation-config /><context:component-scan base-package="com.xxx" /><bean id="aBean" />
不,没有重复,我们再次得到了预期的结果:
creating bean B: com.xxx.B@157aa53creating bean C: com.xxx.C@ec4a87creating bean A: com.yyy.A@1d64c37setting A.bbb with com.xxx.B@157aa53setting A.ccc with com.xxx.C@ec4a87
这是因为两个标签都注册了相同的处理工具(
即使你多次注册处理工具,Spring仍将确保它们仅执行一次魔术。此XML:
<context:annotation-config /><context:component-scan base-package="com.xxx" /><bean id="aBean" /><bean id="bla" /><bean id="bla1" /><bean id="bla2" /><bean id="bla3" />
仍会产生以下结果:
creating bean B: com.xxx.B@157aa53creating bean C: com.xxx.C@ec4a87creating bean A: com.yyy.A@25d2b2setting A.bbb with com.xxx.B@157aa53setting A.ccc with com.xxx.C@ec4a87
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)