Springboot基于enable模塊驅(qū)動

enable作為模塊驅(qū)動在Spring Farmework、Spring Boot、Spring Cloud使用,都是通過注解的形式以@enable作為前綴,一些常用注解如

框架 注解 模塊
Spring Framework @EnableWebMvc Web MVC模塊
Spring Framework @EnableTransactionmanagement Web MVC模塊
Spring Framework @EnableCacheing Cacheing模塊
Spring Framework @EnableMBeanExport JMX模塊
Spring Framework @EnableWebFlux Web Flux模塊
Spring Framework @EnableAspectJAutoProxy AspectJ模塊
Spring Boot @EnableAutoConfiguration 自動裝配模塊
Spring Boot @EnableWebManagementContext Actuator模塊
Spring Boot @EnableConfigurationProperties 配置屬性綁定模塊
Spring Boot @EnableOauth2Sso OAuth2單獨登錄模塊
Spring Cloud @EnableEurekaServer eureka服務模塊
Spring Cloud @EnableConfigServer 配置服務器模塊
Spring Cloud @EnableFeignClients Feign客戶端模塊
Spring Cloud @EnableZuulProxy 服務網(wǎng)關zuul模塊
Spring Cloud @EnableCircuitBreaker 服務熔斷模塊

如何自定義enable開發(fā)?

基于ImportSelector實現(xiàn)注解驅(qū)動

自定義接入類型

Access為接入類型的接口,下文的RPC接入和REST接入基于這個實現(xiàn),定義兩個接口,一個為啟動,一個停止,內(nèi)部嵌套一個枚舉用于標識是哪一種接入

public interface Access {
    /**
     * 初始化配置
     */
    void start();

    /**
     * 銷毀配置
     */
    void stop();

    enum Type{
        REST,
        RPC
    }
}

定義RPC和REST的實現(xiàn)

REST實現(xiàn),只是簡單的打印方法

public class RestAccess implements Access{
    @Override
    public void start() {
        System.out.println("rest接入配置");
    }

    @Override
    public void stop() {
        System.out.println("rest接入銷毀配置");
    }
}

RPC實現(xiàn)

public class RpcAccess implements Access{
    @Override
    public void start() {
        System.out.println("rpc接入配置");
    }

    @Override
    public void stop() {
        System.out.println("rpc接入銷毀配置");
    }
}

自定義注解EnableAccess

接入類型為RPC或者REST,AccessImportSelector在下一步驟實現(xiàn)

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AccessImportSelector.class)
public @interface EnableAccess {
    /**
     * 接入類型
     * @return
     */
    Access.Type type();
}

實現(xiàn)ImportSelector

定義AccessImportSelector實現(xiàn)ImportSelector,分別獲取注解信息,根據(jù)注解獲取接入類型,根據(jù)接入類型選擇不同的接入類型

public class AccessImportSelector implements ImportSelector{
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        //讀取EnableAccess中所有的屬性方法
        Map<String, Object> annotationAttributes =  annotationMetadata.getAnnotationAttributes(EnableAccess.class.getName());
        //獲取屬性為type的屬性方法
        Access.Type type = (Access.Type )annotationAttributes.get("type");
        //導入的類名稱數(shù)組
        String [] importClassName = new String[0];
        switch (type){
            case RPC:
                //設置為RPC,返回RpcAccess組件
                importClassName = new String[]{RpcAccess.class.getName()};
                break;
            case REST:
                //設置為REST,返回RestAccess組件
                importClassName = new String[]{RestAccess.class.getName()};
        }
        return importClassName;
    }
}

使用

在primarySource也就是這里的DemoApplication上使用注解EnableAccess,選擇接入方式,就會初始化不通的接入組件

@SpringBootApplication
@EnableAccess(type=Access.Type.REST)
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        Access access = context.getBean(Access.class);
        access.start();
        access.stop();
    }

}

基于ImportBeanDefinitionRegistrar實現(xiàn)注解驅(qū)動

這里其它步驟一樣,主要區(qū)別是注解里面Import的類變了,這里是基于基于ImportBeanDefinitionRegistrar實現(xiàn)注解驅(qū)動實現(xiàn)

自定義ImportBeanDefinitionRegistrar

public class AccessImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        ImportSelector importSelector = new AccessImportSelector();
        //篩選class名稱集合
        String[] selectedClassNames = importSelector.selectImports(annotationMetadata);
        Stream.of(selectedClassNames)
                .map(BeanDefinitionBuilder::genericBeanDefinition)
                .map(BeanDefinitionBuilder::getBeanDefinition)
                .forEach(beanDefinition ->{
                    //注冊beanDefinition到beanDefinitionRegistry
                    BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition,beanDefinitionRegistry);
                });
    }
}

EnableAccess注解變更

這里import導入了AccessImportBeanDefinitionRegistrar

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AccessImportBeanDefinitionRegistrar.class)
public @interface EnableAccess {
    /**
     * 接入類型
     * @return
     */
    Access.Type type();
}

實現(xiàn)

RPC接入

type=Access.Type.RPC

@SpringBootApplication
@EnableAccess(type=Access.Type.RPC)
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        Access access = context.getBean(Access.class);
        access.start();
        access.stop();
    }

}

REST接入

type=Access.Type.REST

@SpringBootApplication
@EnableAccess(type=Access.Type.REST)
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        Access access = context.getBean(Access.class);
        access.start();
        access.stop();
    }

}

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!

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

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

  • 前言 最近在學習Spring Boot相關的課程,過程中以筆記的形式記錄下來,方便以后回憶,同時也在這里和大家探討...
    龍二丶閱讀 787評論 0 3
  • 微服務架構(gòu)模式的核心在于如何識別服務的邊界,設計出合理的微服務。但如果要將微服務架構(gòu)運用到生產(chǎn)項目上,并且能夠發(fā)揮...
    java菜閱讀 3,039評論 0 6
  • spring官方文檔:http://docs.spring.io/spring/docs/current/spri...
    牛馬風情閱讀 1,842評論 0 3
  • 引言:我們很多人,經(jīng)常努力了很多年,最終卻發(fā)現(xiàn)依然毫無改變。 而答案,就在今天的內(nèi)容當中。 從14年開始,每年年底...
    曹冬賀閱讀 2,037評論 0 1
  • 昨天媽說到那個郵政銀行理財,今天打電話去了解了,是一個中郵保險,果斷讓她停了,流動性不好,利息很低。這件事后,...
    姚常春閱讀 161評論 0 0

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