之间的区别

问题:

我正在学习Spring 3,我似乎没有把握<context:annotation-config><context:component-scan>背后的功能
从我所看到的,他们似乎处理不同的注释(@Required,@Autowired etc vs @Component,@Repository,@Service等),但也从我读过的注册同一个bean后处理器类。
为了混淆我,<context:component-scan>上有一个annotation-config属性
有人可以清楚地看到这些标签吗?有什么不同,有别的,被另一个取代,他们相互完成,我需要其中之一吗?

回答:

 <context:annotation-config>用于激活已经在应用程序上下文中注册的bean中的注释(无论是使用XML定义还是通过包扫描)。
 <context:component-scan>也可以执行<context:annotation-config>,但<context:component-scan>也可以扫描包以在应用程序上下文中查找和注册bean。
我会用一些例子来显示差异/相似之处。
让我们从ABC类型的三个Bean的基本设置开始,BC被注入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" 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>

加载上下文产生以下输出:

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

好的,这是预期的输出。但这是“老式”的春天。现在我们有注释,所以可以使用这些注释来简化XML。
首先,让bean A上的bbbccc属性自动连接,如下所示:

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" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />

当我加载上下文时,我得到以下输出:

creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf

好的,这是错的!发生了什么?为什么我的房产不是自动连线的?
那么注释是一个很好的功能,但是它们自己什么都不做。他们只是注释东西。您需要一个处理工具来查找注释并对其进行处理。
 <context:annotation-config>抢救。这会激活它在其定义的相同应用程序上下文中定义的bean上发现的注释的操作。
如果我将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" />

当我加载应用程序上下文时,我得到了正确的结果:

creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b

好的,这很好,但是我已经从XML中删除了两行,并添加了一行。这不是很大的区别。注释的想法是它应该删除XML。
所以我们来删除XML定义,并用注释替换它们:

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;
  }
}

在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@1be0f0a
creating bean C: com.xxx.C@80d1ff

嗯…有东西丢了为什么?
如果你在课堂上看起来很好,class 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@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9

就是这样!现在你没有XML定义,你有注释。
作为最后一个例子,保留注释类ABC,并将以下内容添加到XML中,我们在加载上下文后会得到什么?

<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

我们仍然得到正确的结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

即使不通过扫描获得类A的bean,处理工具仍然在所有注册的bean上由<context:component-scan>应用
在应用程序上下文中,即使是在XML中手动注册的A
但是如果我们有以下的XML,如果我们已经指定了<context:annotation-config /><context:component-scan>

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />

不,没有重复,我们再次得到预期的结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

这是因为两个标签注册相同的处理工具(如果指定了<context:component-scan><context:annotation-config />可以省略),但是Spring只需要运行它们一次。
即使你自己多次登录处理工具,Spring仍然会确保他们只有一次魔法;这个XML:

<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />

仍将产生以下结果:

creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87

好的,关于它,
我希望这些信息以及来自@Tomasz Nurkiewicz和@Sean Patrick Floyd的回复是您需要了解的
 <context:annotation-config><context:component-scan>工作。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Difference between vs

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

7 + 1 =