一、@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(){...}