Spring自动配置之condition条件判断下篇
作者:lxrqiyuan
前言
本文章接上一篇文章继续谈一谈condition的一些用法。
案例
上一篇文章我提的一个需求时导入jedis坐标后才能加载该Bean,否则不加载,那我们能不能将类的判断定义为动态的,就不能写死,判断哪个或哪些字节码文件可以动态指定。
那么这时我们就要用到自定义条件注解。
首先我们来自定义一个注解ConditionOnClass
自定义的注解上要加上Conditionnal注解,而它的参数仍然是一个或多个字节码文件,就可以实现相同的功能,注解内的方法返回值时一个字符串数组。
package cs.yangtze.springboot_condition.condition; import org.springframework.context.annotation.Conditional; import java.lang.annotation.*; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(ClassCondition.class) public @interface ConditionOnClass { String[] value(); }
然后我们在自定义配置文件config中添加自定义注解,注解中的参数为一个或多个想要判断的条件,即当能够使用或者存在该类的时候才能创建User的Bean对象。此处我导入的是这两个类,当然也可以换成其它的。
package cs.yangtze.springboot_condition.config; import cs.yangtze.springboot_condition.condition.ClassCondition; import cs.yangtze.springboot_condition.condition.ConditionOnClass; import cs.yangtze.springboot_condition.entity.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @Configuration public class UserConfig { @Bean @ConditionOnClass({"redis.clients.jedis.Jedis","com.alibaba.fastjson.JSON"}) public User user(){ return new User(); } }
最后去实现condition接口,matches方法的参数代码中有注释。如果你不知道Map里面是什么,你可以打印出来,它的键就是value,值就是一个数组,也就是上面提到的自定义注解中传入的参数,即{“redis.clients.jedis.Jedis”,“com.alibaba.fastjson.JSON”}。
package cs.yangtze.springboot_condition.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; import java.util.Map; public class ClassCondition implements Condition { /** * @param context 上下文对象,用于获取环境对象,IOC容器以及ClassLoader对象 * @param metadata 注解元对象,可用于获取注解定义的属性值 * @return */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //需求:动态的判断是否有该类 Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName()); String[] value = (String[]) map.get("value"); try { for (String className : value) { Class<?> aClass = Class.forName(className); } } catch (Exception e) { flag = false; } return flag; } }
最后能够成功创建user的bean对象,你可以删去pom文件中的任何一个依赖,最终都不能成功创建bean对象。
删去redis或fastJson依赖后都不能成功创建
总结
Condition小结:
(1)自定义条件类:自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值。matches方法的两个参数:
· context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
· metadata:元数据对象,用于获取注解属性。
(2)判断条件:在初始化Bean时,使用@Conditional(条件类.class)注解。
但是一般我们都不用自定义条件注解,因为SpringBoot为我们提供了一些常用的条件注解:
· ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
· ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
· ConditionalOnMissingbean:判断环境中没有该Bean才初始化Bean
到此这篇关于Spring自动配置之condition条件判断下篇的文章就介绍到这了,更多相关Spring condition条件判断内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!