Springboot基于enable模块驱动

本文详细介绍在Spring Framework、Spring Boot及Spring Cloud中如何自定义@Enable注解来启用特定模块,包括通过ImportSelector和ImportBeanDefinitionRegistrar两种方式实现,以及具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

enable作为模块驱动在Spring Farmework、Spring Boot、Spring Cloud使用,都是通过注解的形式以@enable作为前缀,一些常用注解如

框架注解模块
Spring Framework@EnableWebMvcWeb MVC模块
Spring Framework@EnableTransactionmanagementWeb MVC模块
Spring Framework@EnableCacheingCacheing模块
Spring Framework@EnableMBeanExportJMX模块
Spring Framework@EnableWebFluxWeb Flux模块
Spring Framework@EnableAspectJAutoProxyAspectJ模块
Spring Boot@EnableAutoConfiguration自动装配模块
Spring Boot@EnableWebManagementContextActuator模块
Spring Boot@EnableConfigurationProperties配置属性绑定模块
Spring Boot@EnableOauth2SsoOAuth2单独登录模块
Spring Cloud@EnableEurekaServereureka服务模块
Spring Cloud@EnableConfigServer配置服务器模块
Spring Cloud@EnableFeignClientsFeign客户端模块
Spring Cloud@EnableZuulProxy服务网关zuul模块
Spring Cloud@EnableCircuitBreaker服务熔断模块

如何自定义enable开发?

基于ImportSelector实现注解驱动

自定义接入类型

Access为接入类型的接口,下文的RPC接入和REST接入基于这个实现,定义两个接口,一个为启动,一个停止,内部嵌套一个枚举用于标识是哪一种接入

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

    /**
     * 销毁配置
     */
    void stop();

    enum Type{
        REST,
        RPC
    }
}
定义RPC和REST的实现

REST实现,只是简单的打印方法

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

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

RPC实现

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在下一步骤实现

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

定义AccessImportSelector实现ImportSelector,分别获取注解信息,根据注解获取接入类型,根据接入类型选择不同的接入类型

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");
        //导入的类名称数组
        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实现注解驱动

这里其它步骤一样,主要区别是注解里面Import的类变了,这里是基于基于ImportBeanDefinitionRegistrar实现注解驱动实现

自定义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();
}

实现

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();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值