@Conditional
@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
<code>@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition Conditions} that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class extends Condition>[] value();
}
/<code>
从代码中可以看到,需要传入一个Class数组,并且需要继承Condition接口:
<code>@FunctionalInterface
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
/<code>
Condition是个接口,需要实现matches方法,返回true则注入bean,false则不注入。
在SpringBoot中,@Conditional注解并不是孤军奋斗,它们是一个家族,我们来看一下它们其中的几个成员,又都是怎么用的
@ConditionalOnBean
<code>@Bean
@ConditionalOnBean(RedisConnectionFactory.class)
public RedisTemplate<object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<object> template = new RedisTemplate<object>();
template.setConnectionFactory(connectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
/<object>/<object>/<object>/<code>
这个方法上加了@ConditionalOnBean注解,注解里的属性是RedisConnectionFactory。它的意思呢,就是说如果你配置了redis的相关配置信息那么我就实例化RedisTemplate供你进行操作,如果你没有配置redis的相关配置那么我就不实例化。
不仅如此也可以像这样根据bean的名字@ConditionalOnBean(name = “xxxBean”)或者 @ConditionalOnBean(annotation = DemoAnnotation.class)根据注解等等骚操作都可以.
@ConditionalOnMissingBean
@ConditionalOnMissingBean这个仅仅比1多了个Missing,啥意思呢,见名知意,就是不存在某个bean的时候实例化。
@ConditionalOnClass
存在某个类时,才会实例化一个Bean
@ConditionalOnMissingClass
不存在某个类时,才会实例化一个Bean
@ConditionalOnProperty
@ConditionalOnProperty(prefix = “pre”, name = “test”, havingValue = “token”)
它的意思呢就是当存在配置文件中以"pre"为前缀的属性,属性名称为"test",然后它的值为"token"时才会实例化一个类。
还有一个比较好的属性
@ConditionalOnProperty(prefix = “pre”, name = “test”, havingValue = “token”, matchIfMissing = true) matchIfMissing的意思呢就是说如果所有的都不满足的话就默认实现,不管这个属性pre.test是不是等于token
@ConditionalOnJava(如果是Java应用)
@ConditionalOnWebApplication(如果是Web应用)
相关注解还有很多,可以查看org.springframework.boot.autoconfigure.condition
有时候可能这些提供的注解,可能都不合适,那我们能不能自定义呢?答案当然是:可以。那么咱们就自定义一个
- 首先自定义一个规则类 public class MyCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //在这里写你的逻辑,比如说你想a>0时实例化类A,a<0时不实现 return a > 0; } }
- 使用 @Bean @Conditional(MyCondition.class) public A a(){ return new A() }
閱讀更多 程序員進軍SJF 的文章