@Autowired在春季工作 - 详细指南
#java #spring #springboot

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,因为有多个豆类,但含糊不清。