您的位置:首页 > 编程语言 > Java开发

Spring@Autowired注解与自动装配

2015-06-25 17:02 519 查看

1 配置文件的方法

我们编写spring框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean都建议定义成私有的域变量。并且要配套写上get和set方法。

Boss拥有Office和Car类型的两个属性:

1
2
3
4
5
6
7
8
9
10
11

public
class Boss

{
private
Car car;

private
Office office;

//省略 get/setter

@Override
public
String toString()

{

return
"car:" +
car +
"/n" +
"office:" +
office;

}

}

我们在Spring容器中将Office和Car声明为Bean,并注入到Boss Bean中,下面是使用传统XML完成这个工作的配置文件beans.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<?xml
version="1.0"
encoding="UTF-8"
?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
id="boss"
class="Boss">

<property
name="car"
ref="car"/>

<property
name="office"
ref="office"
/>

</bean>

<bean
id="office"
class="Office">

<property
name="officeNo"
value="002"/>

</bean>

<bean
id="car"
class="Car"
scope="singleton">

<property
name="brand"
value="红旗CA72"/>

<property
name="price"
value="2000"/>

</bean>

</beans>

当我们运行以下代码时,控制台将正确打出boss的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13

import
org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public
class Test

{

public
static void
main(String[]
args)
{

String[]
locations =
{"beans.xml"};

ApplicationContext
ctx =
new ClassPathXmlApplicationContext(locations);

Boss boss
= (Boss)
ctx.getBean("boss");

System.out.println(boss);

}

}

2 @Autowired的使用

Spring 2.5引入了@Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowired的使用来消除set,get方法。

下面是@Autowired的定义:

1
2
3
4
5
6
7
8

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD})
public
@interface
Autowired

{
//是否必须满足依赖性检查,默认时,凡是应用了@Autowired注解的属性和方法都必须找到合适的协作者,否则Spring容器会抛出异常,

//通过调整required属性取值能够改变这一行为。
boolean
required()
default true;

}

注意:@Autowired注解能够作用于构建器、属性、方法。这里的方法不局限于设值方法,即setter方法,常见的各种方法都可以应用这一注解。

要使用@Autowired实现我们要精简程序的目的,需要这样来处理:

在applicationContext.xml中加入:

<!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

Spring通过一个BeanPostProcessor对@Autowired进行解析,所以要让@Autowired起作用必须事先在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean。

修改在原来注入Spirng容器中的bean的方法,在域变量上加上标签@Autowired,并且去掉相应的get和set方法。

使用 @Autowired 注释的 Boss.java

1
2
3
4
5
6
7
8

import
org.springframework.beans.factory.annotation.Autowired;

public class
Boss
{

@Autowired
private
Car car;

@Autowired
private
Office office;

}

在applicatonContext.xml中把原来引用的<porpery>标签也去掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

<?xml
version="1.0"
encoding="UTF-8"
?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
该 BeanPostProcessor
将自动起作用,对标注 @Autowired
的 Bean
进行自动注入 -->

<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

<!--
移除 boss Bean
的属性注入配置的信息 -->

<bean
id="boss"
class="Boss"/>

<bean
id="office"
class="Office">

<property
name="officeNo"
value="001"/>

</bean>

<bean
id="car"
class="Car"
scope="singleton">

<property
name="brand"
value="红旗 CA72"/>

<property
name="price"
value="2000"/>

</bean>

</beans>

这样,当 Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring容器中所有Bean,当发现Bean中拥有@Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。

3 @Autowired注入规则

@Autowired默认是按照byType进行注入的,但是当byType方式找到了多个符合的bean,又是怎么处理的?Autowired默认先按byType,如果发现找到多个bean,则又按照byName方式比对,如果还有多个,则报出异常。

例子:

@Autowired

private Car redCar;

1. spring先找类型为Car的bean

2. 如果存在且唯一,则OK;

3. 如果不唯一,在结果集里,寻找name为redCar的bean。因为bean的name有唯一性,所以,到这里应该能确定是否存在满足要求的bean了

@Autowired也可以手动指定按照byName方式注入,使用@Qualifier标签,例如:

@Autowired()

@Qualifier("baseDao" )

因为bean的name具有唯一性,理论上是byName会快一点,但spring默认使用byType的方式注入。另外补充一点:@Resource(这个注解属于J2EE的)的标签,默认是按照byName方式注入的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: