@Conditional、@Primary和@Qualifier

一、@Conditional
  与@Bean结合使用。如果给定的条件计算结果为true(因此,这个bean需要有一个条件计算方法),就会创建magicBean;否则就会忽略magicBean。因此此配置方法也称之为条件化的配置bean。例子如下:

/** 只有当MagicCondional的某个方法返回true时才会创建MagicBean;
  *  当MagicCondional返回false时不会创建MagicBean  */
@Bean
@Conditional(MagicCondional.class)
public MagicBean magicBean(){
    return new MagicBean();
}

  可以给出MagicCondional的例子代码如下:

public MagicCondional implements Conditional(){
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadate){
        return context.getEnvironment().containsProperty("magic");
    }
}

  Conditional接口代码如下:

public interface Conditional(){
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadate);
}

  不过到了Spring4之后,@Profile进行了重构

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documentes
/**可以用@Profile替代@Conditional */
@Conditional(ProfileCondition.class)
public @interface Profile {
    /**
     * The set of profiles for which this component should be registered.
     */
    String[] value();
}

二、@Primary和@Qualifier
1.标志首选bean
  自动装配中遇到的问题:仅有一个bean匹配所需要的结果时,自动装配才是有效的。反之,如果有多个bean匹配的话,就会出现歧义,歧义会阻碍Spring自动装配属性、构造器等。
  例:  

@Autowired
public void setDessert(Dessert dessert){
    this.dessert = dessert;
}
@Component
public class Cake implements Dessert(){...}
@Component
public class Cookie implements Dessert(){...}
@Component
public class IceCream implements Dessert(){...}

  组件扫描的时候,不知道应该调用那个bean,会抛出异常。
  
  如何解决呢?可以使用@Primary。存在歧义默认会使用带@Primary 的bean

@Component
@Primary
public class Cake implements Dessert(){...}

2.限定自动装配的bean
  @Qualifier主要是为了令使用的bean唯一。
  首选bean 的缺点:无法将可选方案的范围限定到唯一一个无歧义性的选项中。
  限定符:在所有的可选bean上进行范围缩小操作,最终能达到只有一个bean满足所规定的限定条件。
  我曾经看到过Spring项目里边使用mongodb,对于mongoBD的装配使用

@Resource(name = "mongoTemplate")
private MongoOperations mongoOperations;

  如果想要替代可以使用:

@Autowired
@Qualifier("mongoTemplate")
private MongoOperations mongoOperations;

  这里使用了@Qualifier注解,他是在引用上使用。当然可以在容器里面标记多个@Qualifier:

@Component
@Qualifier("cold")
@Qualifier("like")
public class Cake implements Dessert(){...}

3.自定义注释
  需要使用@Qualifier,例如:

@Qualifier
public @interface Cold {

}

  现在就可以使用自己定义的@Cold注解:

@Component
@Cold
@Qualifier("like")
public class Cake implements Dessert(){...}

猜你喜欢

转载自blog.csdn.net/u010986518/article/details/82594923
今日推荐