SpringBoot构建微服务实战 之 @Condition*

xiaoxiao2021-02-28  13

SpringBoot构建微服务实战 之 @Condition*

在之前的文章中我们学习了使用 @Import 来注入特定的Bean,本节我们将深入学习一下如何使用Condition 来装配Bean。 @Condition* 时根据不同的 @Condition*注解来装配Bean。


首先我们来看一下SpringBoot 中Spring 提供的@Condition* 具体有哪些。

@Condition* 实例

我们将选择性讲解一下 @Condition* 实例。

AutoConfigurationCondition.java

package com.springBoot.entrance.condition.autoCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; /** * 该类演示SpringBoot 中一些常用的Condition * @author Administrator * */ @Component public class AutoConfigurationCondition { @Bean("onPropertyCondition") @ConditionalOnProperty(name="condition.onPropertyCondition",havingValue="true",matchIfMissing=true) //只有配置文件中(springBoot读取的配置文件)有 condition.onPropertyCondition且该值为 true 时才装配该Bean,如果该配置没有value,使用matchIfMissing=true 也能装配该Bean public Runnable onPropertyCondition(){ return () ->{}; } @Bean("onBean") @ConditionalOnBean(name={"onPropertyCondition","dfgdfg"}) //指定的Bean中只要有一个Bean存在于Spring IOC container 中则该Bean被装配 public Runnable onBeanCondition(){ return () ->{}; } @Bean("missingBean") @ConditionalOnMissingBean(name={"123","dfgdfg"}) //指定的Bean中只要有一个Bean不存在于Spring IOC container 中则该Bean被装配 public Runnable missingBeanCondition(){ return () ->{}; } @Bean("onClass") @ConditionalOnClass(name={"com.google.gson.Gson"}) //指定的class 必须全在classpath中存在 且逻辑 public Runnable onClassCondition(){ return () ->{}; } @Bean("missingClass") @ConditionalOnMissingClass(value={"com.google.gson.Gson",""}) //指定的class 必须都不在classpath 且逻辑 public Runnable missingClassCondition(){ return () ->{}; } }

App.java

//使用SpringBoot 提供的Condition System.out.println(context.getBean("onPropertyCondition")); System.out.println(context.getBean("onBean")); System.out.println(context.getBean("missingBean")); System.out.println(context.getBean("onClass")); //System.out.println(context.getBean("missingClass"));

结果


自定义@Condition*

在使用SpringBoot 中的@Condition 来装配Bean 时,我们可以使用Spring自有的@Condition* 也可以自定义@Condition* 来满足我特定的需求。下面我们将通过一个实例来说明。

新建目录

EncodingConvert.java

package com.springBoot.entrance.condition.customizeCondition; public interface EncodingConvert { }

EncodingConvertConfiguration.java

package com.springBoot.entrance.condition.customizeCondition; import org.springframework.boot.SpringBootConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; /** * @Conditional 一般配合Condition使用,只有接口实现类返回true 时才会被装配 否则不装配 * * @Conditional 作用域: * 方法上:只对该方法起作用 * 类上:该类下面的所有方法都将受影响 * 因而在我们做Condition 限制Bean 装配时可以结合 @Conditional 修饰类和 @Conditional 修饰方法两种灵活作用 */ //@Conditional(GBKCondition.class) //@Conditional(UTF8Condition.class) //@Conditional({GBKCondition.class,UTF8Condition.class}) 必须指定的Bean 都返回了Treu 才生效 @SpringBootConfiguration public class EncodingConvertConfiguration { @Bean @Conditional(UTF8Condition.class) public EncodingConvert createUTF8EncodingConvert() { System.out.println("File Encoding Type = UTF-8"); return new UTF8EncodingConvert(); } @Bean @Conditional(GBKCondition.class) public EncodingConvert createGBKEncodingConvert() { System.out.println("File Encoding Type = GBK"); return new GBKEncodingConvert(); } }

GBKCondition.java

package com.springBoot.entrance.condition.customizeCondition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * 使用@Condition 自定义 condition * @author Administrator * */ public class GBKCondition implements Condition { /*** * 自定义Condition 逻辑但必须实现Condition 接口 * 符合逻辑 返回true * 不符合逻辑返回false */ public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) { //获取文件编码格式 String encodingType = System.getProperty("file.encoding"); if(encodingType != null){ return "gbk".equals(encodingType.toLowerCase()); } return false; } }

GBKEncodingConvert.java

package com.springBoot.entrance.condition.customizeCondition; public class GBKEncodingConvert implements EncodingConvert { }

UTF8Condition.java

package com.springBoot.entrance.condition.customizeCondition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * 使用@Condition 自定义 condition * @author Administrator * */ public class UTF8Condition implements Condition { @Override public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) { //获取文件编码格式 String encodingType = System.getProperty("file.encoding"); if(encodingType != null){ return "utf-8".equals(encodingType.toLowerCase()); } return false; } }

UTF8EncodingConvert.java

package com.springBoot.entrance.condition.customizeCondition; public class UTF8EncodingConvert implements EncodingConvert { }

App.java

//SpringBoot Bean的自动装配 继承 Condition 类============================ //自定义Condition //Run as VM arguments // -Dstr.encoding=BGK/UTF-8 来指定str编码类型(或者其中一个) // -Dfile.encoding=BGK/UTF-8 来制定读取文件的编码方式(只能其中一个) System.out.println("EncodingType = "+System.getProperty("file.encoding")); System.out.println(context.getBeansOfType(EncodingConvert.class)); System.out.println("Condition end line ==============================================================================="); System.out.println();

结果

输入参数

结果

特别说明:在本自定义@Condition中

我们将 file 的编码方式设置成了 UFT-8 则按照代码逻辑 只有 UTF8Condition.java 将被装配到Spring IOC Container中

在 EncodingConvertConfiguration.java 我们声明:当 UTF8Condition.java 类实例被装配时 返回 UTF8EncodingConvert(),当 GBKCondition.java 类实例被装配时 返回 GBKEncodingConvert()。

因而按照逻辑而言最终返回的应该是 UTF8EncodingConvert 的实例。


小结

在使用@Condition* 选择性装配Bean 我们可以选择Spring 自有的 @Condition* 也使用 @Conditional 来自定义我们的Condition Logical。

在使用自定义 @Condition* 时我们须 实现 Condition 接口。具体请参考代码。

转载请注明原文地址: https://www.6miu.com/read-2350054.html

最新回复(0)