zoukankan      html  css  js  c++  java
  • SpringBoot自定义Condition注解

     

    https://www.cnblogs.com/zhixiang-org-cn/p/9703736.html

     
     
        最近碰到个这样的需求,需要同一套代码适配个版本数据库(数据库不同,且部分表的字段及关联关系可能会不同),即这套代码配置不同的数据库都能跑。项目采用的框架为SpringBoot+Mybatis。经过一番思考,思路如下:
        (1)在业务层(service)和数据访问层(Mapper)之间添加一层适配层,用来屏蔽数据库的差异
        (2)适配层中代码均采用接口加实现类的方式,不同的数据库用的实现类不同
        (3)业务层(service)中全部采用面向接口编程
        (4)项目启动后只实例化和数据库相匹配的适配层实现类
        实现上面的一个关键点是对bean的实例化添加一个条件判断来控制。其实SpringBoot里面新增了很多条件注解,能实现这个功能。但是都有些局限性,最终是采用自定义条件注解的方案。
     

    一、SpringBoot自带的注解ConditionalOnProperty

            这个注解不做过多的解释,只说通过这个注解怎么实现我们的功能。
    假设我们application.properties中配置一个配置项为
    
    
      
    #bean实例化条件配置项

    conditionKey=1.0 
     
        那么只需要加上@ConditionalOnProperty的name和havingValue就能实现,只有配置文件中name对应的配置项的值和havingValue内容一致才实例化这个对象。
    针对我们上面配置的application.properties的内容,@ConditionalOnProperty的使用案例如下面代码所示
    
    
     
     
    // 仅当conditionKey==1.0的时候实例化这个类
    @Component
    @ConditionalOnProperty(name = "conditionKey", havingValue = "1.0")
    public class Manage1Impl  implements  MyManage{
        @Override

       public void sayHello() {
            System.out.println("我是实现类01");
        }
        @PostConstruct
        public void init() {

           this.sayHello();
        }
    }
     
     
        这个注解的局限性这个注解的havingValue里面只能配置一个值。
        由于项目个性化需求,希望这个havingValue可以配置多个值,name对应的配置项的Value只要满足havingValue里面多个值的就表示匹配正确。即,havingValue里面可以配置多个值,name对应配置项的值来和havingValue匹配时,采用逻辑或匹配,满足一个值就算匹配正确。

    二、自定义条件注解

    (1)思路

            注解里面有2个属性,具体如下
    • name:String类型,用来接受application.properties的配置项的key
    • havingValue:String数组类型,用来和name对应key的Value进行匹配

    (2)定义注解

    
    
      
     
     
    package com.zxy.config;
    import org.springframework.context.annotation.Conditional;
    import java.lang.annotation.*;
    /**
     * 自定义条件注解
     * @author ZENG.XIAO.YAN
     * @version 1.0
     * @Date 2019-04-150
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Documented
    @Conditional(CustomOnPropertyCondition.class)
    public @interface CustomConditionalOnProperty {
        /**
         * 条件变量的name
         */
        String name() default "";
     
        /**
         * havingValue数组,支持or匹配
         */
        String[] havingValue() default {};
    }
     
     
     

    (3)定义注解的匹配规则

    
    
       
     
     
    package com.zxy.config;
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    import java.util.Map;
    /**
     * 自定义条件注解的验证规则

    * @author ZENG.XIAO.YAN
     * @version 1.0
     * @Date 2019-04-15
     */
    public class CustomOnPropertyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
            Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(CustomConditionalOnProperty.class.getName());
            String propertyName = (String) annotationAttributes.get("name");
            String[] values = (String[]) annotationAttributes.get("havingValue");
            if (0 == values.length) {
                return false;
            }
            String propertyValue = conditionContext.getEnvironment().getProperty(propertyName);
            // 有一个匹配上就ok
            for (String havingValue : values) {
                if (propertyValue.equalsIgnoreCase(havingValue)) {
                    return true;
                }
            }
            return false;
        }
    }
     

    (4)使用案例

        直接参考下面2图吧
            
     
            
     

    三、小结

        自定义Condition注解,主要就2步
    (1)定义一个条件注解
    (2)定义一个条件的校验规则
  • 相关阅读:
    软工小白菜的团队介绍和采访
    团队作业第二次——团队Github实战训练
    团队作业第一次—团队展示和项目展示
    week5:Technology: Internets and Packets
    week3:History: The Web Makes it Easy to Use
    week2:History: The First Internet
    week4:History: Commercialization and Growth
    week1:History: Dawn of Electronic Computing
    第二日会议博客
    第一日会议博客
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/11303874.html
Copyright © 2011-2022 走看看