好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

如何使用SpringBootCondition更自由地定义条件化配置

Conditional如何使用

@Conditional 是 SpringFramework 的功能, SpringBoot 在它的基础上定义了 @ConditionalOnClass , @ConditionalOnProperty 的一系列的注解来实现更丰富的内容。

定义一个自定义标签

?

1

2

3

4

5

6

7

8

9

10

11

12

13

import com.example.conditional.MyConditional;

import org.springframework.context.annotation.Conditional;

 

import java.lang.annotation.*;

 

@Target ({ElementType.TYPE,ElementType.METHOD})

@Retention (RetentionPolicy.RUNTIME)

@Documented

@Conditional (MyConditional. class )

public @interface MyConditionalIAnnotation {

   String key();

   String value();

}

自定义Conditional

?

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

import com.example.conditional.interfaceI.MyConditionalIAnnotation;

import org.springframework.boot.autoconfigure.condition.ConditionOutcome;

import org.springframework.boot.autoconfigure.condition.SpringBootCondition;

import org.springframework.context.annotation.ConditionContext;

import org.springframework.context.annotation.Conditional;

import org.springframework.core.type.AnnotatedTypeMetadata;

 

import java.util.Map;

 

 

public class MyConditional extends SpringBootCondition {

 

   @Override

   public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {

     Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(MyConditionalIAnnotation. class .getName());

     Object key = annotationAttributes.get( "key" ); //

     Object value = annotationAttributes.get( "value" );

     if (key == null || value == null ){

       return new ConditionOutcome( false , "error" );

     }

 

     //获取environment中的值

     String key1 = context.getEnvironment().getProperty(key.toString());

     if (value.equals(key1)) {

       //如果environment中的值与指定的value一致,则返回true

       return new ConditionOutcome( true , "ok" );

     }

     return new ConditionOutcome( false , "error" );

 

   }

}

config配置

?

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

import com.example.conditional.interfaceI.MyConditionalIAnnotation;

import com.example.conditional.service.MyConditionalService;

import org.apache.log4j.Logger;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

 

@Configuration

public class MyConditionalConfig {

   public static Logger logger=Logger.getLogger(MyConditionalService. class );

 

   /**

    * 判断MyConditional 是否符合条件,是则运行MyConditionalService

    * @return

    */

   @MyConditionalIAnnotation (key = "com.example.conditional" , value = "lbl" )

   @ConditionalOnClass (MyConditionalService. class )

   @Bean

   public MyConditionalService initMyConditionService() {

     logger.info( "MyConditionalService已加载。" );

     return new MyConditionalService();

   }

}

配置文件:application.propeties

?

1

2

3

4

5

6

spring.application.name=gateway

server.port=8084

#conditional 动态配置,判断该值是否等于lbl,是则创建MyConditionalService实例

com.example.conditional=lbl

#支持自定义aop

spring.aop.auto= true

SpringBootCondition 定义条件化配置

1 条件化配置

Spring提供了多种实现化条件化配置的选择,如ConditionalOnProperty和ConditionalOnClass等。

用法如下:

?

1

@ConditionalOnProperty (prefix = "pkslow" , name = "service" , havingValue = "larry" )

还有:

?

1

2

3

4

5

6

@ConditionalOnBean (仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)

@ConditionalOnClass (某个 class 位于类路径上,才会实例化一个Bean)

@ConditionalOnExpression (当表达式为 true 的时候,才会实例化一个Bean)

@ConditionalOnMissingBean (仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)

@ConditionalOnMissingClass (某个 class 类路径上不存在的时候,才会实例化一个Bean)

@ConditionalOnNotWebApplication (不是web应用)

但有时候我们需要更灵活的自定义条件配置,这时可以通过继承SpringBootCondition类来实现。

2 继承SpringBootCondition

自己根据需求实现自己的判断逻辑,我的实现如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

public class PkslowCondition extends SpringBootCondition {

  @Override

  public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {

   BindResult<List<String>> maxBindResult = Binder.get(context.getEnvironment()).bind( "pkslow.condition.max" , Bindable.listOf(String. class ));

   BindResult<List<String>> minBindResult = Binder.get(context.getEnvironment()).bind( "pkslow.condition.min" , Bindable.listOf(String. class ));

 

   if ( (maxBindResult.isBound() && !maxBindResult.get().isEmpty()) && (minBindResult.isBound() && !minBindResult.get().isEmpty()) ) {

    List<String> maxs = maxBindResult.get();

    List<String> mins = minBindResult.get();

    int max = Integer.parseInt(maxs.get( 0 ));

    int min = Integer.parseInt(mins.get( 0 ));

 

    if (max < 1000 && min > 0 ) {

     return ConditionOutcome.match();

    }

 

   }

 

   return ConditionOutcome.noMatch( "pkslow.condition.max/pkslow.condition.min not matches" );

  }

}

表示需要有配置属性pkslow.condition.max/pkslow.condition.min才会生效,并且要求max<1000且min>0。

3 使用

完成自定义的条件类后,就可以使用它来限定一个配置类是否要生效了,使用如下:

?

1

2

3

4

5

6

7

8

@Conditional (PkslowCondition. class )

@Configuration

public class PkslowConfig {

   @PostConstruct

   public void postConstruct() {

     System.out.println( "PkslowConfig called" );

   }

}

4 总结

代码请查看:https://github测试数据/LarryDpk/pkslow-samples

以上就是如何使用SpringBootCondition更自由地定义条件化配置的详细内容,更多关于SpringBootCondition 定义条件化配置的资料请关注其它相关文章!

原文链接:https://HdhCmsTestpkslow测试数据/archives/springbootcondition

查看更多关于如何使用SpringBootCondition更自由地定义条件化配置的详细内容...

  阅读:12次