26、springboot的自动配置03--核心功能--自定义条件注解及使用

开发自己的自动配置------开发自己的条件注解

★ 自定义条件注解

好处有两个:
1. 真正掌握Spring boot条件注解的本质。
2. 项目遇到一些特殊的需求时,也可以开发自己的自定义条件注解来解决问题。

自定义条件注解:
▲ 所有自定义注解其实都是基于@Conditional的 ,@Conditional的可以说一切条件注解的老祖宗。
▲ 使用@Conditional定义新条件注解关键就是要有个Condition实现类,
  该Condition实现类就负责条件注解的处理逻辑:它所实现的matches()方法决定了该条件注解的要求是否得到满足。 

 (1)实现Condition实现类, 该实现必须实现matches方法。
      该方法就是条件注解的判断逻辑
      换而言之,条件注解是否通过检查,就是看该方法的返回值是否为true

 (2)定义条件注解——它是一个注解。
      在该注解上使用@Conditional来指定该条件注解实际其作用的Condition实现类。、

步骤理解:定义一个注解,写一些属性,比如成员变量,然后再创建一个类,用来写这个自定义注解的逻辑,就这两步而已。

代码演示:

步骤:
1、自定义一个条件注解。
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第1张图片
2、定义一个处理类,用来处理自定义条件注解的处理逻辑。这个类需要实现 Condition 接口,并重写这个接口的 matches 方法,这个matches 方法就是要写自定义条件注解的处理逻辑。

自己整理的思路解释:
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第2张图片

写代码时的思路解释,截图:
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第3张图片
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第4张图片

3、进行测试,因为自定义条件注解里面的value属性,在yml配置文件都有对应上,所以这个自定义条件注解检查通过,使用这个注解能通过、生效。
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第5张图片

思路分析:
1、自定义一个条件注解,其实也是一个普通注解,之所以是条件注解,主要是看这个注解的处理类是怎么处理的。
2、自定义一个条件注解的处理类,实现Condition 接口,并且重写 matches 方法,在matches方法中写自定义条件注解的处理检查逻辑
3、使用这个注解,在自定义的DateFormat这个bean上面添加这个自定义条件注解@ConditionalCustom,只有这个注解的条件都检查通过了,这个 DatFormat 这个bean 才能生效。

自定义条件注解的值的传递及条件判断的顺序如图:
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第6张图片

处理自定义注解逻辑的类的解释
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第7张图片
26、springboot的自动配置03--核心功能--自定义条件注解及使用_第8张图片

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;
    }
}

你可能感兴趣的:(springboot,spring,boot,java,spring)