SpringBoot自定义Condition注解实战 - 第402篇

在前面的文章中《Spring Boot条件注解》,我们了解到了Spring Boot给我们提供了很多的条件注解,但是并不能满足所有的场景。

有这么一种需求可能就满足不了了:需要同一套代码适配个版本数据库(数据库不同,且部分表的字段及关联关系可能会不同)。

实现的关键点是对bean的实例化添加一个条件判断来控制。其实SpringBoot里面新增了很多条件注解,能实现这个功能。但是都有些局限性,最终是采用自定义条件注解的方案。

一、SpringBoot自带的注解ConditionalOnProperty

         这个注解不做过多的解释,只说通过这个注解怎么实现我们的功能。

假设我们application.properties中配置一个配置项为:

  1. #bean实例化条件配置项
  2. conditionKey=1.0

那么只需要加上@ConditionalOnProperty的name和havingValue就能实现,只有配置文件中name对应的配置项的值和havingValue内容一致才实例化这个对象。

针对我们上面配置的application.properties的内容,@ConditionalOnProperty的使用案例如下面代码所示:

  1. @Component
  2. @ConditionalOnProperty(name="conditionKey" ,havingValue = "1.0")
  3. public class DAOAdapterImpl implements DAOAdapter{
  4. public void save(){
  5. System.out.println("我是实现类01");
  6. }
  7. }

         这个注解的局限性:这个注解的havingValue里面只能配置一个值

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

二、自定义条件注解

2.1 思路

注解里面有2个属性,具体如下:

(1)name:String类型,用来接受application.properties的配置项的key

(2)havingValue:String数组类型,用来和name对应key的Value进行匹配

2.2 定义注解

         我们自定义注解:

  1. import org.springframework.context.annotation.Conditional;
  2. import java.lang.annotation.*;
  3. /**
  4. * 自定义条件注解
  5. *
  6. * @author 悟纤「公众号SpringBoot」
  7. * @date 2021-10-12
  8. * @slogan 大道至简 悟在天成
  9. */
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Target({ElementType.TYPE, ElementType.METHOD})
  12. @Documented
  13. @Conditional(CustomOnPropertyCondition.class)
  14. public @interface CustomConditionalOnProperty {
  15. /**
  16. * 条件变量的name
  17. */
  18. String name() default "";
  19. /**
  20. * havingValue数组,支持or匹配
  21. */
  22. String[] havingValue() default {};
  23. }

2.3 定义注解的匹配规则

         重点的实现就是匹配规则:

  1. import org.springframework.context.annotation.Condition;
  2. import org.springframework.context.annotation.ConditionContext;
  3. import org.springframework.core.type.AnnotatedTypeMetadata;
  4. import java.util.Map;
  5. /**
  6. * 自定义条件注解的验证规则
  7. *
  8. * @author 悟纤「公众号SpringBoot」
  9. * @date 2021-10-12
  10. * @slogan 大道至简 悟在天成
  11. */
  12. public class CustomOnPropertyCondition implements Condition {
  13. @Override
  14. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  15. //获取注解上配置的信息
  16. Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(CustomConditionalOnProperty.class.getName());
  17. String propertyName = (String)annotationAttributes.get("name");
  18. String[] values = (String[]) annotationAttributes.get("havingValue");
  19. if (0 == values.length) {
  20. return false;
  21. }
  22. //获取环境中的配置的信息(这里也就是application.properties的信息)
  23. String propertyValue = context.getEnvironment().getProperty(propertyName);
  24. // 有一个匹配上就ok
  25. if(propertyValue != null){
  26. for (String havingValue : values) {
  27. if (havingValue.equalsIgnoreCase(propertyValue)) {
  28. return true;
  29. }
  30. }
  31. }
  32. return false;
  33. }
  34. }

2.4 使用

         使用起来是很简单的,如下示例:

@CustomConditionalOnProperty(name="conditionKey" ,havingValue = {"1.0","3.0"})

三、小结

自定义Condition注解,主要就2步:

(1)定义一个条件注解

(2)定义一个条件的校验规则


  1. 购买完整视频,请前往:http://www.mark-to-win.com/TeacherV2.html?id=287