First explain the meaning of the two annotations @Primary and @Qualifier: @Primary means that among many identical beans, the bean annotated with @Primary is preferred. The @Qualifier annotation specifies whether a bean is eligible for injection.
The idea of the sample code is: 1. An interface Dessert and three implementation classes of this interface, 2. Automatically inject the Dessert interface into a class (AbrahamLincoln), 3. Use the automatic scanning mechanism to automatically create beans.
If the @Primary and @Qualifier annotations are not used, the following error will inevitably occur: NoUniqueBeanDefinitionException.
The sample code is as follows: [Use @Primary to solve the problem]
The code for the Dessert interface is as follows:
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.stereotype.Component; 4 5 /** 6 * Created by ${秦林森} on 2017/6/9. 7 */ 8 @Component 9 public interface Dessert { 10 void amI(); 11 }
Cake's code is as follows:
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.beans.factory.annotation.Qualifier; 4 import org.springframework.context.annotation.Primary; 5 import org.springframework.stereotype.Component; 6 7 /** 8 * Created by ${秦林森} on 2017/6/9. 9 */ 10 @Component 11 public class Cake implements Dessert { 12 @Override 13 public void amI() { 14 System.out.println("I am cake"); 15 } 16 }
The code for the cookie is as follows:
package com.advancedWiring.ambiguityInAutowiring; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; /** * Created by ${Qin Linsen} on 2017/6/9. */ @Component public class Cookie implements Dessert { @Override public void amI() { System.out.println("I am cookie"); } }
The code for IceCream is as follows:
package com.advancedWiring.ambiguityInAutowiring; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; /** * Created by ${Qin Linsen} on 2017/6/9. */ @Component @Primary//注意这里用了@Primary这个注解。 public class IceCream implements Dessert{ @Override public void amI() { System.out.println("I am ice cream"); } }
DessertConfig的代码如下:
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 6 /** 7 * Created by ${秦林森} on 2017/6/9. 8 */ 9 @Configuration 10 /** 11 * 用@ComponentScan自动扫描创建bean 12 */ 13 @ComponentScan(basePackageClasses = Dessert.class) 14 public class DessertConfig { 15 16 }
测试类的代码如下:
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 /** 6 * Created by ${秦林森} on 2017/6/9. 7 */ 8 public class AmbiguityTest { 9 public static void main(String[] args) { 10 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(DessertConfig.class); 11 Dessert dessert = ac.getBean(Dessert.class); 12 dessert.amI(); 13 } 14 }
二:用@Qualifier这个注解来解决问题:
核心代码如下:
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.beans.factory.annotation.Qualifier; 4 import org.springframework.context.annotation.Primary; 5 import org.springframework.stereotype.Component; 6 7 8 /** 9 * Created by ${秦林森} on 2017/6/9. 10 */ 11 @Component 12 @Qualifier("crispy") 13 public class Cookie implements Dessert { 14 @Override 15 public void amI() { 16 System.out.println("I am cookie"); 17 } 18 }
1 package com.advancedWiring.ambiguityInAutowiring; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Qualifier; 5 import org.springframework.stereotype.Component; 6 7 /** 8 * Created by ${秦林森} on 2017/6/9. 9 */ 10 @Component 11 public class AbrahamLincoln { 12 private Dessert dessert; 13 14 public Dessert getDessert() { 15 return dessert; 16 } 17 @Autowired 18 @Qualifier("crispy") 19 public void setDessert(Dessert dessert) { 20 this.dessert = dessert; 21 } 22 }