开发自己的自动配置------开发自己的条件注解
★ 自定义条件注解
好处有两个:
1. 真正掌握Spring boot条件注解的本质。
2. 项目遇到一些特殊的需求时,也可以开发自己的自定义条件注解来解决问题。
自定义条件注解:
▲ 所有自定义注解其实都是基于@Conditional的 ,@Conditional的可以说一切条件注解的老祖宗。
▲ 使用@Conditional定义新条件注解关键就是要有个Condition实现类,
该Condition实现类就负责条件注解的处理逻辑:它所实现的matches()方法决定了该条件注解的要求是否得到满足。
(1)实现Condition实现类, 该实现必须实现matches方法。
该方法就是条件注解的判断逻辑
换而言之,条件注解是否通过检查,就是看该方法的返回值是否为true
(2)定义条件注解——它是一个注解。
在该注解上使用@Conditional来指定该条件注解实际其作用的Condition实现类。、
步骤理解:定义一个注解,写一些属性,比如成员变量,然后再创建一个类,用来写这个自定义注解的逻辑,就这两步而已。
代码演示:
步骤:
1、自定义一个条件注解。
2、定义一个处理类,用来处理自定义条件注解的处理逻辑。这个类需要实现 Condition 接口,并重写这个接口的 matches 方法,这个matches 方法就是要写自定义条件注解的处理逻辑。
自己整理的思路解释:
写代码时的思路解释,截图:
3、进行测试,因为自定义条件注解里面的value属性,在yml配置文件都有对应上,所以这个自定义条件注解检查通过,使用这个注解能通过、生效。
思路分析:
1、自定义一个条件注解,其实也是一个普通注解,之所以是条件注解,主要是看这个注解的处理类是怎么处理的。
2、自定义一个条件注解的处理类,实现Condition 接口,并且重写 matches 方法,在matches方法中写自定义条件注解的处理检查逻辑
3、使用这个注解,在自定义的DateFormat这个bean上面添加这个自定义条件注解@ConditionalCustom,只有这个注解的条件都检查通过了,这个 DatFormat 这个bean 才能生效。
自定义条件注解的值的传递及条件判断的顺序如图:
处理自定义注解逻辑的类的解释
package cn.ljh.app.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
//这是一个自定义条件注解的处理类
//条件注解就是这个注解指定了一些条件,只有项目中的代码符合这些条件,被该注解修饰的类或方法才能生效。
//这个类是用来处理自定义条件注解的处理逻辑的。
public class MyCondition implements Condition {
//这个方法就是我们自定义条件注解的判断逻辑
//就是自定义的条件注解是否通过检查,就是看这个方法的返回值是否为true。
//通过检查可以理解这个条件注解的条件在项目中是存在的,比如某个配置文件存在某个条件注解指定的属性值,就能通过检查
//ConditionContext 获取当前项目的配置环境(比如配置文件信息)
//AnnotatedTypeMetadata 用来获取指定注解的全部属性
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//AnnotatedTypeMetadata 相当于是一个反射工具类,用来获取注解的信息
//可用于获取指定注解(ConditionalCustom)的全部属性(value),方法返回值是一个map结构
Map<String, Object> attrs = annotatedTypeMetadata.getAnnotationAttributes(ConditionalCustom.class.getName());
//因为我们自定义的条件注解ConditionalCustom只定义了一个value属性,所以我们要在返回的map结构中获取它的属性值
//获取自定义注解的value属性,这些值是字符串数组。
String[] value = (String[]) attrs.get("value");
//然后就是根据这些属性值来做一些逻辑判断,就是只有这些逻辑判断都成立,这个自定义条件注解才能通过检查、生效。
//此处我们的逻辑,要求项目必须是value所指定的每个配置属性都存在
//为了检查每个配置属性都存在,因此要先获取springboot的配置环境(配置文件)
Environment env = conditionContext.getEnvironment();
//遍历value属性值的每个元素-----要求每个元素指定的配置属性都是存在的,该条件注解才能通过检查、生效。
for (String propName : value){
//判断配置环境是否有注解中对应这些属性
if(env.getProperty(propName) == null){
//如果通过 propName 获取对应的配置属性有一个不存在,那么这个自定义条件注解的检查就没有通过,返回false
return false;
}
}
//如果for循环的每个元素对应的配置属性都存在,那就说明这个自定义注解通过检查,因此返回true。
return true;
}
}