一、引言
Spring提供了一系列以Enable开头的注解,这些注解本质上是激活Spring的某些管理功能,比如
@EnableCaching
,@EnableTransactionManagement
。很多文章解析原理都会讲到ImportSelector
,以及ImportBeanDefinitionRegistrar
,本文不做赘述,本文探讨另一种Enable
实现方式。
二、代码实现
假设我们有一个BizCommands
service接口类,有一个接口#fetchById
,有默认的实现。
public interface BizCommands {
default Optional<String> fetchById(long id){
return Optional.of("default");
}
}
根据业务类型的不同我们有不同的实现,暂时具体实现BizCommandsImpl
类。
public class BizCommandsImpl implements BizCommands {
@Override
public Optional<String> fetchById(long id){
//todo fetch from external
final String data = "";
return Optional.ofNullable(data);
}
}
在测试环境下我们也许会用接口类里面具体接口的默认实现,但是在预发或者正式环境下我们会用到具体的业务实现。所以需要有一个Enable*
去完成这样的切换。
下面是具体实现。
首先添加一个自动配置类,BizCommands
接口的默认匿名实现,那么fetchById
的具体实现就是default 接口的实现。
@Configuration
public class BizAutoConfigure {
@Bean
@ConditionalOnMissingBean
public BizCommands doctorCommands(){
return new BizCommands() {};
}
}
接着添加一个@interface
注解EnableDataFromExternal
。此注解内部实现了一个配置类,配置类里的BizCommands
的实现是具体的业务实现。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({
EnableDataFromExternal.DataFromExternalConfigure.class
})
public @interface EnableDataFromExternal {
class DataFromExternalConfigure {
@Primary
@Bean
BizCommands doctorCommands(){
return new BizCommandsImpl();
}
}
}
然后工程目录resources/META-INF
下创建文件spring.factories
。
文件内容为
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
$(your path).BizAutoConfigure
此时开发就已经完成。
然后在项目里面引入此依赖包,在启动类上配置注解EnableDataFromExternal
,此时fetchById
就是具体的业务实现,取消注解,就是默认的接口实现。