SpringBoot:如何書寫一個(gè)自定義的Enable*注解

Spring提供了一系列Enable*的自定義注解,這些注解本質(zhì)上只是用于啟用spring boot管理的一些功能特性,比如 [EnableWebMvc] 注解會(huì)激活提供基于springmvc的web功能支持, [EnableAsync]注解會(huì)激活異步的功能支持。
我比較好奇這些自定義注解是如何工作的,進(jìn)而促使我寫出這篇文章記錄我的理解,這些自定義注解的支持,可以理解為SPI的一部分,如果后續(xù)的內(nèi)部實(shí)現(xiàn)有變化,對(duì)應(yīng)的支持可能會(huì)中斷。

1.新建自定義的注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface EnableCustomFeature {}

2.應(yīng)用此注解到配置類

@Configuration
@EnableCustomFeature 
public class CustomFeatureConfig {}

3.這時(shí)候需要在EnableCustomFeature 類中通過@Import的方式引入一系列需要前置處理的Bean類

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfiguration.class)
@interface EnableCustomFeature {}

上述通過@Import方式做的原因,主要是將@Import標(biāo)記的配置類中的bean作為ApplicationContext處理

@Configuration
class SomeBeanConfiguration {
 
    @Bean
    public String aBean1() {
        return "aBean1";
    }
 
    @Bean
    public String aBean2() {
        return "aBean2";
    }
}

使用Selector選擇器啟用Enable自定義注解

自定義Enable*注解也可以實(shí)現(xiàn)復(fù)雜的功能,可以通過的上下文啟用不同的bean實(shí)現(xiàn)功能。在Springboot中@EnableCaching就是這樣的例子,可以通過不同的緩存實(shí)現(xiàn)來激活對(duì)應(yīng)的bean配置。

示例如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfigurationSelector.class)
public @interface EnableCustomFeatureSelector {
    String criteria() default "default";
}

上述示例中,自定義的注解中有一個(gè)criteria自定義注解屬性字段,默認(rèn)值為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",就會(huì)加載SomeBeanConfigurationDefault, 否則就是加載SomeBeanConfigurationType1。

參考鏈接:http://www.java-allandsundry.com/2015/04/spring-enable-annotation-writing-custom.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容