和之间的区别

和之间的区别,第1张

和之间的区别

<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只会运行它们一次。

即使你多次注册处理工具,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


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4926106.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存