在last post中,我们已经看到如何在多个地方使用@Autowired
来注入依赖的豆子。弹簧框架处理组件之间的依赖关系,并基于字段,设置器或构造函数注入适当的对象。
问题?
当春季上下文具有相同类型的多种豆时会发生什么?哪个对象弹簧框架注入@Autowired
注释?
如果我们在春季上下文中有单一的bean类型,则框架没有任何歧义,它将在需要的任何地方注入依赖的bean。
春季框架如何处理这种情况?
当春季框架陷入需要在@Autowired
依赖项之一中注入相同类型的多种豆的情况时,它将遵循three
步骤以解决歧义。
默认情况下,IOC容器将始终寻找bean的
class type
以注入。
步骤1:查找具有相同参数/字段名称的BEAN名称。
Spring ioc容器将寻找bean名称,等于所述的@Autowired
注释中提到的参数名称,setter参数,构造函数参数。
// field injection
@Autowired
private SomeBean bean; // here spring looks for bean with name "bean" in context
// setter injection
@Autowired
public void setSomeBean(SomeBean bean1){ // here spring looks for bean with name "bean1" in context to inject.
this.bean = bean1;
}
// constructor injection
@Autowired
public Example(SomeBean bean2){ // here spring looks for bean with name "bean2" in context to inject.
this.bean=bean2;
}
如果找不到匹配的名称bean,请按照步骤2
进行操作
步骤2:春季IOC容器寻找标记为@Primary
bean的bean
因此,如果找不到匹配的名称bean,则Spring ioc容器检查是否有多个bean中有任何标记为@Primary
bean的bean,如果是的,则注入该bean。
@Primary // this is primary bean
@Bean
public SomeBean myBean(){
return new SomeBean("Hello");
}
@Bean // this is normal bean
public SomeBean myOtherBean(){
return new SomeBean("Welcome");
}
// when @Autowired is invoked, as we have multiple beans of same class type, @Primary bean will be injected for below wiring.
@Autowired
public SomeBean bean; // as no name bean matching with myBean, myOtherBean so Primary bean will be injected here.
如果在上下文中找不到
进行操作@Primary
bean,请按照步骤3
步骤3:Spring IOC容器将寻找@Qualifier注释,并找到具有匹配名称的BEAN。
现在,ioc容器检查是否使用了@Qualifier
,是否找到了@Qualifier
中提到的bean的名称并注入。
@Bean
public SomeBean myBean(){
return new SomeBean("Hello");
}
@Bean
public SomeBean myOtherBean(){
return new SomeBean("Welcome");
}
// when @Autowired is invoked, as we have multiple beans of same class type, @Primary bean not found checks name with @Qualifier and injects below
@Autowired // here qualifier used is "myBean" so IoC will inject the bean with name myBean
public Example(@Qualifier("myBean")SomeBean bean){
this.bean = bean;
}
使用@qualifier是有益的,因为参数名称可以根据开发人员的选择来更改以提高代码的可读性,但不会影响由于使用的限定词名称而引起的自动发动机。
如果遵循上述所有步骤并且找不到匹配的豆,则会抛出一个例外NoUniqueBeanDefinitionException
,因为有多个豆类,但含糊不清。