注解装配(注入)是spring在2.5版本引入的新特性,使用注解装配和在XML文件中使用autowire属性自动装配类似,只是使用注解方式允许更细粒度的装配(更完善),我们可以对属性有选择性的进行自动装配。在以往,我们对属性进行注入的时候,需要在XML文件中进行如下配置:
<!-- 属性注入 -->
<bean id="Duke" class="com.bean.Wife">
<property name="age" value="25"></property>
</bean>
<!-- 构造器注入 -->
<bean id="Duke" class="com.bean.Wife">
<constructor-arg value="25" />
</bean>
对于只含有少量Bean的应用来说,使用XML配置并不会显得特别麻烦,但是对于一个含有大量Bean的应用来说,任然使用XML配置就显得越来越复杂,基于减少XML配置的内容,spring出现了两种减少XML配置的方式:
1:自动装配(autowiring)让spring自动识别如何装配Bean的依赖关系
2:自动检测(autodiscovery)比自动装配更进一步,让spring自动识别哪些类需要被自动装配为Bean
自动装配有两种方式,一种是在XML文件中使用autowire自动装配,一种是使用注解的方式进行自动装配,虽然两者在装配过程中并没有太大差别,但是在平时的使用过程中,注解的方式用的更多,因为相对于在XML中自动装配来说,注解方式支持更细粒度的装配,我们可以选择性的标注某一个属性来对应用自动装配。那么如何使用注解方式进行自动装配呢?
在使用注解方式进行自动装配之前,我们需要在XML配置文件中使用开启它(注意使用context命名空间时需要在XML配置文件中进行声明),spring支持三种方式的自动装配:
1:spring自有的@Autowired
2:JSR-330的@Inject
3:JSR-250的@Resource
一:使用@Autowired
使用@Autowired注解对属性进行装配的时候,我们可以对属性本身,属性set方法或者构造器进行注解(需要注意的是此时我们的XML文件中对Bean的定义不能少,只是可以去掉或者),其注解代码如下:
@Autowired//对构造器进行注解
public void setAge(int age){
this.age = age;
}
@Autowired//对属性进行注解,此时大可以删掉get/set方法
private int age;</span>
@Autowired//对构造器进行注解
public Wife(int age) {
this.age = age;
}
如上所示,当我们使用@Autowired进行注解的时候,spring会在XML文件中找到对用的Bean,然后对属性进行注入,但是,我们在使用@Autowired的时候,需要注意两点,一是没有与注解匹配的Bean,二是存在多个与注解匹配的Bean,如果出现这两种情况,就会抛出NoSuchBeanDefinitionException异常,如何解决这个问题呢?spring提供了通过设置@Autowired的required属性为false来设置自动装配可选(也就是说遇到没有与注解匹配的Bean这种状况,被注入属性的值会被设置为null),required属性可以用于@Autowired注解的任何地方,但是当使用构造器进行注入的时候,智能有一个构造器可以设置required为true,其他构造器只能设置required为false。
@Autowired(required=false)//对构造器进行注解
public Wife(int age) {
this.age = age;
}
另外一种情况是,当存在多个Bean满足装配条件,spring该做何处理呢?在这里,我们可以使用@Qualifier注解来帮助@Autowired限定哪一个Bean才是所需的
@Autowired
@Qualifier("wife")
private Wife wife ;
在上诉代码中,@Qualifier将注入ID为wife的Bean,在这里可以理解为@Qualifier将@Autowired的byType自动装配显示的转化为了byName装配。
二:使用@Inject
@Inject注解方式和@Autowired注解方式基本相同,使用@Autowired注解的地方同样可以换成@Inject,@Inject也可以对属性,set方法或者构造器进行注解,但是@Inject没有required属性,因此,被@Inject注解的依赖关系必须存在,如果不存在,则会抛出异常,@Inject对于处理存在多个Bean的情况使用的是@Named属性进行限定的,代码如下:
@Autowired
@Named("wife")
private Wife wife ;
@Resource在使用上依然类似于@Autowired注解,只不过@Resource默认以名称进行匹配,@Resource有两个重要的属性,name和type,当没有指定@Resource的name或者type属性时,@Resource默认以名称进行匹配,如果没有匹配到,则以类型进行匹配,但是一旦设置@Resource的name属性,那么@Resource则只能以名称进行匹配。
在使用以上三种注解方式的时候,需要在XML文件中配置以下信息,该配置隐式注册了多个注释进行解析处理的处理器,AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanProcessor,RequiredAnnotationBeanPostProcessor。如果没有注册解析处理器,但是又在使用的话,则会报错。