Handling the ambiguity of Spring's use of @Autowired autowiring

@Autowired uses byType injection by default, and @Qualifier uses byName
To illustrate the ambiguity of autowiring, suppose the setDessert() method is annotated with the @Autowired annotation:
@Autowired
public void setDessert(Dessert dessert){
    this.dessert=dessert;
}
    In this example, Dessert is an interface, and there are three classes that implement this interface, Cake, Cookies, and IceCream:
@Component
public class Cake implements Dessert{...}
@Component
public class Cookies implements Dessert{...}
@Component
public class IceCream implements Dessert{...}
Because all three implementations use the @Component annotation, during component scanning, they can be discovered and created as beans in the Spring application context. Then when Spring tries to autowire the Dessert parameter in setDessert(), it doesn't have a unique, unambiguous optional value. At this point, Spring will throw NoUniqueBeanDefinitionException;
When ambiguity occurs, Spring provides a variety of alternatives to solve such problems:


1. Indicate the preferred bean
Autowiring ambiguities can be avoided by setting one of the optional beans as the primary bean when declaring beans. example:
@Component
@Primary
public class IceCream implements Dessert{...}
Or explicitly declare IceCream via Java configuration, then the @Bean method should look like this:
@Bean
@Primary
public Dessert iceCream(){
    return new IceCream();
   }
This is also possible if the bean is configured using XML. The <bean> element has a primary attribute to specify the preferred bean:
<bean id="iceCream" class="com.desserteater.IceCream" primary="true" />
The effect is the same regardless of which method is used to represent the preferred bean. But it doesn't work if two or more preferred beans are marked
2. Limit autowired beans
The @Qualifier annotation is the primary way to use qualifiers. It can be used in conjunction with @Autowired and @Inject to specify which bean to inject when injecting. For example, we want to make sure IceCream is injected into setDessert():
@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
    this.dessert=dessert;
}
Create custom qualifiers
       Instead of relying on the beanID as the qualifier, we can set our own qualifier for the bean. All that needs to be done here is to add the @Qualifier annotation to the bean declaration. For example, it can be combined with @Component as follows:
@Component
@Qualifier("cold")
public class IceCream implements Dessert{...}
At this point the cold qualifier is assigned to the IceCream bean. When autowiring wants to inject IceCream, referencing the cold qualifier is fine.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324709011&siteId=291194637