condition(二)

"SpringBoot学习记录"

Posted by yangsir on December 2, 2023

“Yeah It’s on. ”

在condition(一)中redis.clients.jedis.Jedis是写死的,不能灵活运用。。。

需求二:将类的判断定义为动态的。判断哪个字节码文件存在可以动态指定。

1
2
3
4
5
6
7
8
9
10
//ConditionOnClass.java

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(classCondition.class)
public @interface ConditionOnClass {
    String[] value();
}

1
2
3
4
5
6
7
8
9
10
11
12
//UserConfig

@Configuration
public class UserConfig {

    @Bean
    /*@Conditional(classCondition.class)*/
    @ConditionOnClass("redis.clients.jedis.Jedis")
    public User user(){
        return new User();
    }
}

新建了一个注解ConditionOnClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class classCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //导入jedis坐标后创建User
        //怎么才能知道,导入了jedis
        //思路 判断redis.clients.jedis.Jedis文件是否存在
        /*boolean flag = true;
        try {
            Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;*/
        //通过注解属性值导入value指定坐标后创建User
        //获取注解属性值
        Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
        System.out.println(map);
        String[] value = (String[]) map.get("value");

        boolean flag = true;
        try {
            for (String className : value) {
                System.out.println(className);
                System.out.println(value);
                Class<?> cls = Class.forName(className);
            }
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;
    }
}

现在,就可以在userConfig中自定义标签属性值了

小结

自定义条件:

​ 1、定义条件类:自定义类实现Condition接口,重写matches方法,在matches中进行逻辑判断,返回boolean值。matches方法两个参数:

​ context: 上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。

​ metadate:元数据对象,用于获取注解属性。

​ 2、判断条件:在初始化Bean时,使用@Conditional(条件类.class)注解

SpeingBoot提供的常用条件注解:

​ ConditionalOnProperty: 判断配置文件中是否有对应属性和值才初始化Bean

​ ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean

​ ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean

完整代码在_doc/condition2中