Spring Boot学习(二十一):Spring Boot中经常看到的Conditional注解,原来是这个作用

前言

Spring Boot系列: 点击查看Spring Boot系列文章


@Conditional注解

这个注解在Spring4中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean

声明:

//作用域为类或者方法上
@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();

}

可以看到,Conditional注解只有一个value属性, value属性为一个Class数组,并且需要实现Condition接口的类。

Condition接口

Condition接口只有一个matches方法,这个方法是用来确定条件是否匹配。返回true表示条件匹配,组件可以被注册。返回false则不能注册

public interface Condition {

	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

}

matches方法

matches方法有两个参数,一个为ConditionContext (条件上下文),通过它我们可以获取很多有用的信息。AnnotatedTypeMetadata 为注解元数据

以下为ConditionContext 的源码方法

public interface ConditionContext {

	/**
	 *返回一个BeanDefinitionRegistry ,BeanDefinitionRegistry 包含了bean的注册信息和我们定义bean的信息
	 */
	BeanDefinitionRegistry getRegistry();

	/**
	 * 返回保存bean的bean工厂(BeanFactory),从BeanFactory,我们可以获取容器中的任意一个bean
	 */
	@Nullable
	ConfigurableListableBeanFactory getBeanFactory();

	/**
	 * 返回当前的运行环境,environment 持有所有的配置信息
	 */
	Environment getEnvironment();

	/**
	 * 返回当前使用的资源加载器
	 */
	ResourceLoader getResourceLoader();

	/**
	 * 返回 类加载器
	 */
	@Nullable
	ClassLoader getClassLoader();

}

@Conditional使用

下面,我来演示一下如何通过配置文件和@Conditional注解来控制一个bean的注册

1、首先,我们创建一个实现Condition 接口的类,在该类上的matches方法写相应的条件判断。我这里是通过配置文件的"is.open.condition"属性是否为true,如果不为true则返回false,则不能注册组件。为true则注册组件。

public class OpenConditonal implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        Boolean property = context.getEnvironment().getProperty("is.open.condition",boolean.class);

        if (property!=null&&property){
            return true;
        }
        return false;
    }
}

2、在配置类的注册方法加上 @Conditional注解,参数是我们上面定义的条件类,这样bean的注册就要通过我们定义的条件类才能注册

@Configuration
public class ConditionConfig {

    @Bean
    @Conditional(OpenConditonal.class)
    public Teacher teacher(){
        Teacher teacher=new Teacher();
        teacher.setId("1");
        teacher.setAge("20");
        System.out.println("注册teacher类");
        return teacher;
    }

}

3、结果

当我在配置文件加上is.open.condition=true,bean能成功注册,在控制台输出注册teacher类

当我没在配置文件加is.open.condition,或者填false时,bean不能注册

注意:当我们在其他bean注入一些可能不存在的bean时,最好将required属性设为false,这样避免bean不存在时报错

例:

@Autowired(required = false)
private xxxBean xxxBean 

@Conditional的派生注解

注解								说明
@ConditionalOnSingleCandidate	当给定类型的bean存在并且指定为Primary的给定类型存在时,返回true

@ConditionalOnMissingBean		当给定的类型、类名、注解、昵称在beanFactory中不存在时返回true.各类型间是or的关系

@ConditionalOnBean				与上面相反,要求bean存在。例:@ConditionalOnBean(name="redisTemplate")

@ConditionalOnMissingClass		当给定的类名在类路径上不存在时返回true,各类型间是and的关系

@ConditionalOnClass				与上面相反,要求类存在

@ConditionalOnCloudPlatform		当所配置的CloudPlatform为激活时返回true	

@ConditionalOnExpression		spel表达式执行为true

@ConditionalOnJava				运行时的java版本号是否包含给定的版本号.如果包含,返回匹配,否则,返回不匹配

@ConditionalOnProperty			要求配置属性匹配条件

@ConditionalOnJndi				给定的jndi的Location 必须存在一个.否则,返回不匹配

@ConditionalOnNotWebApplication	web环境不存在时

@ConditionalOnWebApplication	web环境存在时

@ConditionalOnResource			要求制定的资源存在
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值