Spring和SpringBoot中针对单一接口多种实现的支持

最近在工作中接触到了需要一个接口多种实现的这种情况,类似于hibernate选择对应方言的情况。我遇到的情况是上传文件的过程中可能存在多种文件系统。需要在配置文件中进行配置来确定使用哪种方式上传文件,Spring提供了@Conditional注解来进行支持,我们需要继承@Condition注解实现自己的规则。
而SpringBoot则提供了更简单的实现方式使用@ConditionOnProperty加上一些简单的属性即可完成、

Spring中提供的@Conditional注解实现单接口多实现类配置

直接上代码

public class DefaultCondition implements Condition {

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
	      Environment environment = context.getEnvironment();

	        String implPrefix = environment.getProperty("fileSystemType");
	        if (StringUtils.isEmpty(implPrefix)) {
	            return true;
	        }
				return false;

	}

}

这就是继承@Conditional所实现的条件。那么如何使用呢?直接在对应条件的实现来上加入注解即可。如下

@Service
@Conditional(DefaultCondition.class)
public class ConditionDefaultServiceImpl implements ConditionService {

	@Override
	public void sayHello() {
		System.out.println("默认实现");		
	}

}

SpringBoot对上述条件注解的支持

SpringBoot则更为简单。将上述条件做了更简便的实现直接在实现类上加入@ConditionOnProperty即可,例如

@ConditionalOnProperty(prefix = "custom.os", name = "name", havingValue = "linux",matchIfMissing=true)
@Service
public class ConditionDefaultServiceImpl implements ConditionService {

	@Override
	public void sayHello() {
		System.out.println("默认实现");		
	}

}
@ConditionalOnProperty(prefix = "custom.os", name = "name", havingValue = "windows")
@Service
public class ConditionServiceImpl implements ConditionService {

	@Override
	public void sayHello() {
		System.out.println("条件实现");
	}
			
	
}

@ConditionOnProperty可以直接获取application.properties中的元素的值,上述属性的值的意思分别为

  • String[] value() default {}; //数组,获取对应property名称的值,与name不可同时使用

  • String prefix() default “”;//property名称的前缀,可有可无

  • String[] name() default {};//数组,property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用

  • String havingValue() default “”;//可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置

  • boolean matchIfMissing() default false;//缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错

  • boolean relaxedNames() default true;//是否可以松散匹配,至今不知道怎么使用的

更多思考

上述只是在Spring框架内的实现。那如果我们脱离了Spring框架怎么办呢?。在寻找解决方案的过程中我了解到了Java SPI的实现。但是对比上述方式来说略显复杂了一点。。在此就不再说明。大家可以自行查看。

本文参考
ConditionalOnProperty的使用

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__0809 返回首页