@Autowired注解(转)

5.6.4 @Autowired注解

自Spring诞生以来,<bean/>的autowire和dependency-check属性便一直存在。当JDK 5.0正式发布后,Spring针对dependency-check属性引入了对应的@Required。同理,它针对autowire属性引入了对应的@Autowired注解,其定义摘录如下。


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

//是否必须满足依赖性检查
boolean required() default true;
}


@Autowired注解能够作用于构建器、属性、方法。这里的方法不局限于设值方法,即setter方法,常见的各种方法都可以应用这一注解。比如,位于autowiringdemo项目中的TestBean1类的testBean2和testBean3属性应用了这一注解,具体如下。


@Autowired(required=false)
private TestBean2 testBean2;

@Autowired
private TestBean3 testBean3;


为启用这一注解,AutowiredAnnotationBeanPostProcessor必须定义在XML配置文件中,示例如下,摘自autowired.xml。运行时,testBean2和testBean3受管Bean会自动注入到testBean1中。开发者是否注意到@Autowired暴露的required属性,这是承担着依赖性检查任务的重要属性。默认时,凡是应用了@Autowired注解的属性和方法都必须找到合适的协作者,否则DI容器会抛出异常,通过调整required属性取值能够改变这一行为。

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
<bean id="testBean1" class="test.TestBean1"/>

<bean id="testBean2" class="test.TestBean2"/>

<bean id="testBean3" class="test.TestBean3"/>

下面给出了应用于设值方法的@Autowired注解。

@Autowired(required=false)  
public void setTestBean2(TestBean2 testBean2) {
this.testBean2 = testBean2;
}

@Autowired
public void setTestBean3(TestBean3 testBean3) {
this.testBean3 = testBean3;
}

下面给出了应用于构建器的@Autowired注解。

@Autowired(required=false)  
public TestBean1(TestBean2 tb2, TestBean3 tb3) {
this.testBean2 = tb2;
this.testBean3 = tb3;
}

下面给出了应用于普通方法的@Autowired注解。

@Autowired 
public void preparedBean(TestBean2 tb2, TestBean3 tb3){
this.testBean2 = tb2;
this.testBean3 = tb3;
}

除了能够自动注入普通受管Bean外,@Autowired注解还能够注入一些特殊对象,比如受管Bean所在DI容器中的各种元数据对象,示例如下。@Autowired将当前DI容器注入。


@Autowired 
private ApplicationContext ac;


在@Autowired的required属性与@Required注解间进行取舍

@Required是专门用于依赖性检查的注解,而@Autowired注解的required属性也能够用来承担依赖性检查工作。一旦@Required应用到目标设值方法,则DI容器必须成功调用这一设值方法,@Required注解才认为依赖性条件得到满足,否则将抛出异常。相比之下,当我们将@Autowired注解的required属性设置为false时,即使未找到合适的协作者,异常都始终不会被抛出。

5.6.5 细粒度控制Autowiring策略

当多个协作者满足autowire注入条件时,我们可以启用<bean/>元素的primary属性,从而避免异常的抛出。但是,primary属性不能够满足企业级应用的复杂需求,比如多个同一类型的不同协作者需要注入到同一受管Bean的时候。

下面给出了某XML配置示例。

<bean id="testBean2a" class="test.TestBean2"/>  

<bean id="testBean2b" class="test.TestBean2"/>

<bean id="testBean2c" class="test.TestBean2"/>

现在希望将它们分别注入到下面给出的属性中。显然,启用primary属性是不行的,因为一旦启用它,testBean2a、testBean2b、testBean2c将引用到同一受管Bean中。


@Autowired 2.private TestBean2 testBean2a;  

@Autowired
private TestBean2 testBean2b;

@Autowired
private TestBean2 testBean2c;

为此,我们需要启用<qualifier/>元素及@Qualifier注解。调整后的XML配置示例如下。

<bean id="testBean2a" class="test.TestBean2">  
<qualifier value="2a"/>
</bean>

<bean id="testBean2b" class="test.TestBean2">
<qualifier value="2b"/>
</bean>

<bean id="testBean2c" class="test.TestBean2">
<qualifier value="2c"/>
</bean>

相应地,属性的定义也需要作相应的调整,下面给出了代码示例。各个@Qualifier注解分别指定了待注入的受管Bean,比如"2a"表示要注入<qualifier/>的value属性取值为"2a"的目标受管Bean。

@Autowired 
@Qualifier("2a")
private TestBean2 testBean2a;

@Autowired
@Qualifier("2b")
private TestBean2 testBean2b;

@Autowired 10.@Qualifier("2c")
private TestBean2 testBean2c;

@Qualifier注解能够作用于属性、参数、类、其他注解等地方,比如下面给出了参数级的使用示例。

@Autowired 
private void preparedBean(@Qualifier("2a") TestBean2 testBean2a, @Qualifier("2b") TestBean2 testBean2b,@Qualifier("2c") TestBean2 testBean2c) {

this.testBean2a = testBean2a;
this.testBean2b = testBean2b;
this.testBean2c = testBean2c;

}

开发者还可以基于@Qualifier注解构建更复杂的Autowiring策略,下面给出了一注解示例。

@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Qualifier
public @interface FineQualifier {

String keyFine() default "";
String valueFine() default "";
}

同使用@Qualifier注解一样,下面给出了@FineQualifier应用示例。

@Autowired 
@FineQualifier(keyFine="key2A", valueFine="value2A")
private TestBean2 testBean2a;

@Autowired
@FineQualifier(keyFine="key2B", valueFine="value2B")
private TestBean2 testBean2b;

@Autowired 10.@FineQualifier(keyFine="key2C", valueFine="value2C")

private TestBean2 testBean2c;

为配合@FineQualifier注解的使用,XML配置文件也需要作相应的调整,下面给出了调整后的配置示例。

<bean id="testBean2a" class="test.TestBean2">  
<qualifier type="test.FineQualifier">
<attribute key="keyFine" value="key2A"/>
<attribute key="valueFine" value="value2A"/>
</qualifier>
</bean>
<bean id="testBean2b" class="test.TestBean2">
<qualifier type="test.FineQualifier">
<attribute key="keyFine" value="key2B"/>
<attribute key="valueFine" value="value2B"/>
</qualifier>
</bean>

<bean id="testBean2c" class="test.TestBean2">
<qualifier type="test.FineQualifier">
<attribute key="keyFine" value="key2C"/>
<attribute key="valueFine" value="value2C"/>
</qualifier>
</bean>

或者,开发者也可以启用<meta/>元素,配置示例如下。当在同一受管Bean中同时指定<qualifier/>和<meta/>元素时,DI容器会优先使用<qualifier/>。

<bean id="testBean2a" class="test.TestBean2">  
<meta key="keyFine" value="key2A"/>
<meta key="valueFine" value="value2A"/>
</bean>
<bean id="testBean2b" class="test.TestBean2">
<meta key="keyFine" value="key2B"/>
<meta key="valueFine" value="value2B"/>
</bean> 10. 11.<bean id="testBean2c" class="test.TestBean2">
<meta key="keyFine" value="key2C"/>
<meta key="valueFine" value="value2C"/>
</bean>

当@FineQualifier注解没有应用类一级的@Qualifier注解时,开发者必须借助如下对象注册它。

<bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">  
<property name="customQualifierTypes">
<set>
<value>test.FineQualifier</value>
</set>
</property>
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值