Spring automatic assembly process ambiguity @Primary custom qualifier annotation @Qualifier

@Autowired

public    void    setDessert(Dessert   dessert){

       this.dessert = dessert;

}

We use @Autowired notes marked setDessert () method, and he relies Dessert interface, but the interface has three Dessert implementation class, and use the @Component notes, then component scans when will these three bean implementation class is instantiated stored in the Spring context, then setDessert () method in the choice, since there are three implementation class, do not know which, Spring will be an error, an exception is thrown NoUniqueBeanDefinitionException.

Solution: We can set one as the preferred bean (use @Primary)

@Component

@Primary

public   class    IceCream   extends   Dessert(){ .........  }

Or by displaying the configuration statement IceCream, then @Bean methods are as follows:

@Bean

@Primiary

public   Dessert   iceCream(){

   return  new   IceCream();

}

If you are using xml configuration, then configuration is as follows:

<bean  id =  "iceCream"   class  =  "com.desserteater.IceCream"   primary="true" />

Either way, the effect is the same, Spring is told in the face of ambiguity of the first bean.

However, if two bean or bean is more preferred to use @ Primiart, Spring will not work, because there is still ambiguity.

@Qualifier

@Qualifier annotation is the main way to use qualifiers, he can be used in conjunction with @Autowired and @Inject, specify when you want to inject the injection of the bean

@Autowired

@Qualifier("iceCream")

public  void   setDessert(Dessert   dessert){
       this.dessert = dessert;

}

This is the simplest example of the use of qualifiers, parameters @Qualifier notes set ID is the bean you want to inject, and all annotations using @Component declared class is created for the bean, and the bean ID headed letter lowercase the class name . Accordingly, @ Qualifier ( "iceCream") points to the bean scan component created, and this instance is the bean class IceCream.

   More precisely speaking, @ Qualifier ( "iceCream") referenced by the bean to have a String "iceCream" as a qualifier. If no qualifiers other words, all the bean will be given a default qualifier, the qualifier and the bean ID is the same, that is led by the class name becomes lowercase letters. Thus the frame will have a "iceCream" qualifier bean into setDessert (method).

Question: It is based on the default beanID led the class name becomes lowercase letters, if the reconstruction of the class, the class name to rename other words, for example, will IceCream rename Gelato, then the above setDesser () method will not be limited by character matching, automatic assembly fails.

Solution: Create a custom qualifier ⬇️⬇️⬇️

Create custom qualifier

Add @Qualifier annotation on the bean statement, he can be used in combination @Component

@Component

@Qualifier("cold")

public   class   IceCream   implements   Dessert {   ......  }

In this case, Cold IceCream qualifiers assigned to the bean, because it is not coupled to a class name, class name can be reconstructed in any of IceCream, without fear of damage automatic assembly above problems. The introduction of cold qualifiers where injected it.

When the display configuration by a java bean time, @ Qualifier can also be used with @Bean

@Bean

@Qualifier("cold")

public  Dessert   iceCream(){

      return  new IceCream();

}

Question: If the same type of classes use the same @Qualifier notes, how to do

Java does not allow multiple repeated notes of the same type on the same entry. Otherwise it will error,

(Note: java 8 allows for repeated notes appear, as long as time itself defines the annotation with @Repeatable comment on it, but Spring's @Qualifier comment does not add @Repeatable notes in the definition.)

//java8中允许使用重复注解的demo,注解需要添加@Repeatable
@Repeatable(Authorities.class)
public @interface Authority {
     String role();
}

public @interface Authorities {
    Authority[] value();
}

public class RepeatAnnotationUseNewVersion {
    @Authority(role="Admin")
    @Authority(role="Manager")
    public void doSomeThing(){ }
}

Such as:

@Component

@Qualifier("cold")

@Qualifier("creamy")

public class   IceCream   implements  Dessert {  ......   }

The above does not allow this operation because @Qualifier @Repeatable no comment, then how to solve it?  

We can create a custom qualifier annotation, with this unique annotation to the bean. We will no longer use @Qualifier ( "code"), but the use of @Code custom annotations, as shown below:

@Target( {ElementType.CONSTRUCTOR,  ElementType.FIELD ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Qualifier

public  @interface  Cold {   }

When not want to use @Qualifier, we adopted the custom qualifier annotations when @Qualifier add annotations, custom annotations have to feel characteristics @Qualifier annotations. They themselves actually became a qualifier annotation.

So if the question above, we can define multiple notes can be hierarchically appear: as

@Component

@Cold

@Creamy

public class   IceCream   implements  Dessert {  ......   }

 

@Component

@Cold

@Fruity

public class   IceCream   implements  Dessert {  ......   }

 

 

Guess you like

Origin blog.csdn.net/m0_37668842/article/details/82748821