Spring提供了一系列Enable*的自定義注解扼劈,這些注解本質上只是用于啟用spring boot管理的一些功能特性往枷,比如 [EnableWebMvc] 注解會激活提供基于springmvc的web功能支持登舞, [EnableAsync]注解會激活異步的功能支持贰逾。
我比較好奇這些自定義注解是如何工作的,進而促使我寫出這篇文章記錄我的理解逊躁,這些自定義注解的支持似踱,可以理解為SPI的一部分,如果后續(xù)的內部實現(xiàn)有變化稽煤,對應的支持可能會中斷核芽。
1.新建自定義的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface EnableCustomFeature {}
2.應用此注解到配置類
@Configuration
@EnableCustomFeature
public class CustomFeatureConfig {}
3.這時候需要在EnableCustomFeature 類中通過@Import的方式引入一系列需要前置處理的Bean類
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfiguration.class)
@interface EnableCustomFeature {}
上述通過@Import方式做的原因,主要是將@Import標記的配置類中的bean作為ApplicationContext處理
@Configuration
class SomeBeanConfiguration {
@Bean
public String aBean1() {
return "aBean1";
}
@Bean
public String aBean2() {
return "aBean2";
}
}
使用Selector選擇器啟用Enable自定義注解
自定義Enable*注解也可以實現(xiàn)復雜的功能酵熙,可以通過的上下文啟用不同的bean實現(xiàn)功能轧简。在Springboot中@EnableCaching就是這樣的例子,可以通過不同的緩存實現(xiàn)來激活對應的bean配置匾二。
示例如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfigurationSelector.class)
public @interface EnableCustomFeatureSelector {
String criteria() default "default";
}
上述示例中哮独,自定義的注解中有一個criteria自定義注解屬性字段,默認值為default察藐,后面我們需要做的就是根據(jù)criteria的值激活兩種不同的bean功能集合:
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
public class SomeBeanConfigurationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
AnnotationAttributes attributes =
AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableSomeBeansSelector.class.getName(), false));
String criteria = attributes.getString("criteria");
if (criteria.equals("default")) {
return new String[]{"enableannot.selector.SomeBeanConfigurationDefault"};
}else {
return new String[]{"enableannot.selector.SomeBeanConfigurationType1"};
}
}
}
@Configuration
class SomeBeanConfigurationType1 {
@Bean
public String aBean() {
return "Type1";
}
}
@Configuration
class SomeBeanConfigurationDefault {
@Bean
public String aBean() {
return "Default";
}
所以如果criteria字段值為 "default"皮璧,就會加載SomeBeanConfigurationDefault, 否則就是加載SomeBeanConfigurationType1分飞。
參考鏈接:http://www.java-allandsundry.com/2015/04/spring-enable-annotation-writing-custom.html