在先前的文章中,我们在 Spring MVC 中学到的东西很少。 在这些教程中,我确实使用了<context:annotation-config>
或<context:component-scan>
之类的标签,但是我没有对这些标签进行详细说明。 我正在写这篇文章,专门列出标签<context:annotation-config>
和<context:component-scan>
之间的区别,以便将来使用它们时,您将知道自己在做什么。
1)两个标签之间的第一个大区别是<context:annotation-config>
是用于在应用程序上下文中激活已注册 bean 中的应用注解。 请注意,bean 是否通过哪种机制注册都没有关系,例如使用<context:component-scan>
或在application-context.xml
文件本身中定义。
2)第二差异是由第一差异本身驱动的。 它确实在上下文中注册了 bean,并且还扫描了 bean 内部的注解并激活了它们。 所以<context:component-scan>
; 做<context:annotation-config>
的工作,但另外它会扫描软件包并在应用程序上下文中注册 bean。
<context:component-scan>
vs <context:annotation-config>
使用示例
我将通过一些示例详细说明这两个标签,这些示例对我们更有意义。 为了使示例简单,我仅创建 3 个 bean,然后尝试以各种方式在配置文件中对其进行配置,然后我们将看到控制台中各种配置之间的区别,其中将输出输出。
供参考,以下是 3 个 bean。 BeanA
另外引用了BeanB
和BeanC
。
package com.howtodoinjava.beans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@SuppressWarnings("unused")
@Component
public class BeanA {
private BeanB beanB;
private BeanC beanC;
public BeanA(){
System.out.println("Creating bean BeanA");
}
@Autowired
public void setBeanB(BeanB beanB) {
System.out.println("Setting bean reference for BeanB");
this.beanB = beanB;
}
@Autowired
public void setBeanC(BeanC beanC) {
System.out.println("Setting bean reference for BeanC");
this.beanC = beanC;
}
}
//Bean B
package com.howtodoinjava.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanB {
public BeanB(){
System.out.println("Creating bean BeanB");
}
}
//Bean C
package com.howtodoinjava.beans;
import org.springframework.stereotype.Component;
@Component
public class BeanC {
public BeanC(){
System.out.println("Creating bean BeanC");
}
}
BeanDemo
类用于加载和初始化应用程序上下文。
package com.howtodoinjava.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
}
}
现在,我们开始编写包含变体的配置文件"beans.xml"
。 在下面的示例中,我将省略模式声明,以继续关注配置本身。
a)仅定义bean
标签
<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Creating bean BeanC
在这种情况下,因为我们没有使用任何属性/引用属性,所以创建了所有 3 个 bean,并且没有在BeanA
中注入任何依赖项。
b)定义bean
标签和ref
属性
<bean id="beanA" class="com.howtodoinjava.beans.BeanA">
<property name="beanB" ref="beanB"></property>
<property name="beanC" ref="beanC"></property>
</bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Creating bean BeanC
Setting bean reference for BeanB
Setting bean reference for BeanC
现在,还创建并注入了 bean。 难怪。
c)仅使用<context:annotation-config/>
<context:annotation-config />
//No Output
正如我已经说过的,<context:annotation-config />
仅在已经发现并注册的 bean 上激活注解。 在这里,我们没有发现任何 Bean,因此什么也没发生。
d)将<context:annotation-config>
与bean
声明一起使用
<context:annotation-config />
<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
在上面的配置中,我们使用<bean>
标签发现了 bean。 现在,当我们使用<context:annotation-config />
时,它只需激活@Autowired
注解,就会在BeanA
内部进行 bean 注入。
e)仅使用<context:component-scan/>
<context:component-scan base-package="com.howtodoinjava.beans" />
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
上面的配置完成了我之前在文章开头提到的两件事。 它会进行 Bean 发现(在基本包中搜索@Component
注解),然后激活其他注解(例如Autowired
)。
f)同时使用<context:component-scan>
和<context:annotation-config>
<context:annotation-config />
<context:component-scan base-package="com.howtodoinjava.beans" />
<bean id="beanA" class="com.howtodoinjava.beans.BeanA"></bean>
<bean id="beanB" class="com.howtodoinjava.beans.BeanB"></bean>
<bean id="beanC" class="com.howtodoinjava.beans.BeanC"></bean>
Output:
Creating bean BeanA
Creating bean BeanB
Setting bean reference for BeanB
Creating bean BeanC
Setting bean reference for BeanC
奇怪! 通过上述配置,我们两次发现了 bean,并且两次激活了注释。 但是输出只打印了一次。 为什么? 因为 spring 具有足够的智能,如果使用相同或不同的方式多次注册任何配置处理,则仅注册一次。酷!
因此,在这里,我将结束本教程,并希望当您在下一个项目中使用这些标签时,它们将为您提供更清晰的画面。 随意下载源代码并使用它。
祝您学习愉快!