SpringBoot源码解析之@Conditional条件注解

@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

SpringBoot源码解析之@Conditional条件注解

有时候可能这些提供的注解,可能都不合适,那我们能不能自定义呢?答案当然是:可以。那么咱们就自定义一个

  1. 首先自定义一个规则类 public class MyCondition implements Condition { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //在这里写你的逻辑,比如说你想a>0时实例化类A,a<0时不实现 return a > 0; } }
  2. 使用 @Bean @Conditional(MyCondition.class) public A a(){ return new A() }


分享到:


相關文章: