zoukankan      html  css  js  c++  java
  • SpringBoot高级-自动配置原理剖析二

    前言:根据剖析一,继续拓展自动配置原理

    新需求:将类的判断定义为动态的,判断哪个字节码文件存在可以动态指定。下面是具体的步骤。

    1、新建一个自定义注解 ConditionOnClass ,顺带解释下注解的作用:
    @Target:注解可以作用的范围(类、方法、属性等)。
    @Retention:注解生效的时机。
    @Documented:可生成文档注释。
    @Conditional:是Spring5提供的条件注解,详细说明和使用见剖析一。

    /**
     * @description:自定义条件注解
     * @date: 2020/10/9 17:52
     * @author: winson
     */
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Conditional(ClassCondition.class)
    public @interface ConditionOnClass {
    
        //可接收参数数组
        String[] value();
    
    }
    

    2、修改自定义User配置类,使用自定义注解

    /**
     * @description:User配置类
     * @date: 2020/10/9 15:25
     * @author: winson
     */
    @Configuration
    public class UserConfig {
    
        @ConditionOnClass("redis.clients.jedis.Jedis")
        @Bean
        public User user() {
            return new User();
        }
    }
    

    3、修改条件类

    /**
     * @description:条件类
     * @date: 2020/10/9 16:24
     * @author: winson
     */
    public class ClassCondition implements Condition {
        /**
         *
         * @param context 上下文对象,可以获取环境、IOC容器、ClassLoader对象
         * @param metadata 注解元对象,可以用于获取注解定义的属性值
         * @return
         */
        //2、需求:导入通过注解属性值value指定坐标后创建Bean
        //思路:获取注解属性值 value
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            boolean flag = true;
            Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
            System.out.println(annotationAttributes);
            return flag;
        }
    }
    

    4、启动程序,测试结果,发现通过注解原对象,获取的annotationAttributes的打印结果,Key为Value,即自定义注解@ConditionOnClass的属性名,Value为自定义注解使用时所赋的值redis.clients.jedis.Jedis。能获取到user的Bean对象,因为我在pom.xml中导入了Jedis的依赖,也证明了我们自定义的注解没有问题,可以生效。

    5、我们再将ClassCondition类修改一下,如果IOC中含有所指定的字节码文件,就返回true,让user的Bean注入到IOC容器中。

        //2、需求:导入通过注解属性值value指定坐标后创建Bean
        //思路:获取注解属性值 value
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            boolean flag = true;
            Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
            String[] values = (String[]) annotationAttributes.get("value");
            try {
                for (String value : values) {
                    Class<?> cls = Class.forName(value);
                }
            } catch (ClassNotFoundException e) {
                flag = false;
            }
            return flag;
        }
    

    6、测试结果

    6.1、将Jedis依赖注释掉,再启动程序,不会再从IOC容器中获取到user的Bean了。

    6.2、我们将自动注解想获取的文件故意写错,Jedis依赖依旧添加,测试结果

    故意将参数(redis.clients.jedis.Jedis.false)写错,再测试

    @Configuration
    public class UserConfig {
    
        @ConditionOnClass("redis.clients.jedis.Jedis.false")
        @Bean
        public User user() {
            return new User();
        }
    
    }
    

    发现结果也不会获取到user的Bean

    小结:该案例实现一个需求,用户想要自动注入user的Bean,必须添加指定的依赖,至于什么依赖,用户自己指定。

  • 相关阅读:
    自动称重系统-3
    自动称重系统-2
    自动称重系统-1
    Qt-序列号生成器
    征战 OSG-序及目录
    Qt-QML-安卓编译问题
    OSG-OSG中的observer_ptr指针
    HZNU Training 22 for Zhejiang Provincial Competition 2020
    树上乱搞
    HZNU Training 21 for Zhejiang Provincial Competition 2020
  • 原文地址:https://www.cnblogs.com/elnimo/p/13787365.html
Copyright © 2011-2022 走看看