Spring 系列之注解开启 annotation-config 和注解扫描 component-scan 区分

本贴最后更新于 1815 天前,其中的信息可能已经时异事殊

前言

Spring 框架对 Bean 进行装配提供了很灵活的方式,下面归纳一下主要的方式:

  • 在 XML 中进行显示配置
  • 在 Java 中进行显示配置
  • 隐式的 bean 发现机制和自动装配

而自动装配就需要注解扫描,这里有两种开启注解扫描的方式,即

<context:annotation-config/>

<context:component-scan>

下面归纳一下这两种注解方式的异同点:

<context:annotation-config/> 注解扫描是针对已经在 Spring 容器里注册过的 Bean

<context:component-scan/> 不仅具备 <context:annotation-config/> 的所有功能,还可以在指定的 package 下面扫描对应的 bean


XML 注册 Bean 方式

下面给出两个类,类 A 和类 B

package com.test;

public class B{
	public B(){
		System.out.println("B类");
	}
}
package com.test;

public class A{
	private B b;
	public void setB(B b){
		this.b = b;
		System.out.println("通过set的方式注入B类");
	}

	public A(){
		System.out.println("A类");
	}
}

然后在 Spring 的 Application.xml 里作如下配置,不开启注解扫描

	<bean id="bBean" class="com.test.B"/>
	<bean id="aBean" class="com.test.A">
		<property name="b" ref="bBean"/>
	</bean>

启动加载 Application.xml 得到如下输出

B类
A类
通过set的方式注入B类

分析:
实例化 B 类,实例化 A 类并注入 B 的实例


annotation 配置注解开启的方式

同样两个类,类 A 和类 B,此处在 A 类中通过 @Autowired 的方式注入 B 的实例

package com.test;
public class B{
	public B(){
		System.out.println("B类");
	}
}
package com.test;
public class A{
	private B b;
	public A(){
		System.out.println("A类");
	}
	
	@Autowired
	public void setB(B b){
		 this.b = b; System.out.println("通过set的方式注入B类"); 
	}
}

然后做如下测试
1.仅仅在 Application.xml 里注册 Bean,不开启扫描

	<bean id="bBean"class="com.test.B"/>
        <bean id="aBean"class="com.test.A"/>

2.仅仅开启扫描,不注册 Bean

	<context:annocation-config/>

以上两种配置方式配置启动加载 Application.xml,得到如下一致结果

B类
A类

会发现 @Autowired 下的方法没有执行,即没有自动注入
然后修改 Application.xml,开启注解

	<context:annocation-config/>
	<bean id="bBean"class="com.test.B"/>
        <bean id="aBean"class="com.test.A"/>

重新启动加载 Application.xml,得到如下输出

B类
A类
通过set的方式注入B类

归纳:<context:annotation-config>:注解扫描是针对已经在 Spring 容器里注册过的 Bean


component 配置注解开启方式

同样两个类,类 A 和类 B,此处在 B 类添加 @Component 注解

package com.test;
public class B{
	public B(){
		System.out.println("B类");
	}
}
package com.test;
@Component
public class A{
	private B b;
	public A(){
		System.out.println("A类");
	}
	
	@Autowired
	public void setB(B b){
		 this.b = b; System.out.println("通过set的方式注入B类"); 
	}
}

然后配置一下 application.xml,开启 annotaion-config 扫描

	<context:annocation-config/>

重新启动加载 Application.xml,得到如下输出

B类
A类

原因:<context:annotation-config>:注解扫描是针对已经在 Spring 容器里注册过的 Bean,Bean 并没有注册过,所以即使开启了 @Autowired、@Component 注解 和配置开启了 annotaion-config 扫描还是加载不到
修改配置文件:

<context:component-scan base-package="com.test"/>

重新启动加载 Application.xml,得到如下输出

B类
A类
通过set的方式注入B类

总结:

<context:annotation-config>:注解扫描是针对已经在 Spring 容器里注册过的 Bean
<context:component-scan>:不仅具备 <context:annotation-config> 的所有功能,还可以在指定的 package 下面扫描对应的 bean
<context:annotation-config /> 和 <context:component-scan> 同时存在的时候,前者会被忽略。
即使注册 Bean,同时开启 <context:annotation-config /> 扫描,@autowire,@resource 等注入注解只会被注入一次,也即只加载一次

  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    944 引用 • 1459 回帖 • 17 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖
  • annotation
    2 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...