使用属性自动注解装配与在xml中使用autowire 属性自动装配并没有太大差别。但是使用注解方式允许更细粒度的自动装配。
Spring容器默认禁止注解装配的。所以使用注解装配要在spring配置中启动它。
最简单的启动方式实在Spring的context命名空间配置中的
<context:annotation-config>;
一档配置完成,我们就可以对代码添加注解,标示Spring应有的属性、方法 和构造器进行自动装配。
Sprng3 支持一下不同的用于自动装配的注解:
1.Spring 自带的@Autowired注解
2.JSR-330 的@Inject注解
3.JSR-250的@Resource注解
使用@Autowired注解
当Spring对属性的set方法使用@Autowired,Spring就会尝试对该方法执行byType自动装配。
也可以注解任一方法和构造器。
@Autowired public class A { private B b; public A(B bb){ this.b = bb; } }
当对构造器进行标注时,@autowired注解表示当创建Bean时,即使在Spring中xml文件中没有使用<constructor-ref>元素配置Bean,该构造器也需要自动装配
另外,我们亦可以用其直接注解属性,并删除setter方法:
@Autowired
private A a;
我们看到,@Autowired不受限于private关键字,是不是其没有限制?
有两种会阻碍注解:
具体来说就是,应用中必须只有一个Bean适合装配到@Autowired注解所标注的属性或参数中,如果没有或者存在多个拼配,就会拍出异常。但是我们有解决办法
可选的自动装配
默认情况下,@Autowired注解的属性或者参数必须是可装配的。如果没有匹配,自动装配就会抛出异常--NoSuchBeanDefinitionException。
但属性不一定要装配,null值也是可以的,在这用情况下,可以通过设置@Autowired的required属性为false
@Autowired(required=false) private Foo foo;
在这里,spring将尝试装配foo属性,如果过哦没诶有找到相匹配的Bean,应用不会有任何问题,foo的属性值会设置为null;
注意:required属性可以用于@Autowired注解所使用的任何地方。但是当使用构造器装配时,只有一个构造器可接将required的值设为true,其他必须为false。。此外,当使用@Autowried标注多个构造器时,Spring就会从所有满足装配条件的构造器中选择入参最多的那个构造器。
限定歧义性的依赖
可能在自动装配时会有多个Bean(至少2个)满足装配条件,这将导致异常。比如我们有两个Bean都实现了TestInterface 接口,为了鉴别哪个是我们需要的,我们可以用Spring的@Qualifier注解。
@Autowried @Qualifier("guitar") private Foo foo
如上所示,@Qualifier注解将尝试注入id为 quitar的Bean。@Quealifier注解缩小了自动装配挑选Bean的范围
创建自定义的限定器(@Qualifier)
package qualifier; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.beans.factory.annotation.Qualifier; @Target({ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface TestQualifier{ }
通过自定义@TestQualifier注解,我们可以用它来代替@Qualifier。可以多次使用限定注解,下面的foo属性是指同时被TestQualifier 和TestQualifier2注解的类型
@Autowried @TestQualifier //自定义A限定器 @TestQualifer2 //自定义B限定器 private Foo foo;