Springboot基于enable模块驱动的实现

 更新时间:2019年08月30日 10:34:04   作者:itrickzhang  
这篇文章主要介绍了Springboot基于enable模块驱动的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

enable作为模块驱动在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 服务网关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();
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 程序员最喜欢的ThreadLocal使用姿势

    程序员最喜欢的ThreadLocal使用姿势

    ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些,下面这篇文章主要给大家介绍了程序员最喜欢的ThreadLocal使用姿势,需要的朋友可以参考下
    2022-02-02
  • Javaweb使用Maven工具与Tomcat的方法详解

    Javaweb使用Maven工具与Tomcat的方法详解

    这篇文章主要为大家详细介绍了Javaweb使用Maven工具与Tomcat的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Java Objects工具类原理及用法详解

    Java Objects工具类原理及用法详解

    这篇文章主要介绍了Java Objects工具类原理及用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Idea里github的图形化操作配置方法

    Idea里github的图形化操作配置方法

    这篇文章主要介绍了Idea里github的图形化操作配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Java8 Stream collect(Collectors.toMap())的使用

    Java8 Stream collect(Collectors.toMap())的使用

    这篇文章主要介绍了Java8 Stream collect(Collectors.toMap())的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 浅谈Java中随机数的几种实现方式

    浅谈Java中随机数的几种实现方式

    这篇文章主要介绍了Java中随机数的几种实现方式,从最简单的Math.random到多线程的并发实现都在本文所列之中,需要的朋友可以参考下
    2015-07-07
  • 启用设置org.slf4j.Logger打印并输出日志方式

    启用设置org.slf4j.Logger打印并输出日志方式

    这篇文章主要介绍了启用设置org.slf4j.Logger打印并输出日志方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • RocketMQ生产消息与消费消息超详细讲解

    RocketMQ生产消息与消费消息超详细讲解

    这篇文章主要介绍了RocketMQ生产消息与消费消息,RocketMQ可用于以三种方式发送消息:可靠的同步、可靠的异步和单向传输。前两种消息类型是可靠的,因为无论它们是否成功发送都有响应
    2022-12-12
  • 解决分页插件pagehelper在SpringBoot不起作用的问题

    解决分页插件pagehelper在SpringBoot不起作用的问题

    这篇文章主要介绍了解决分页插件pagehelper在SpringBoot不起作用的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Java中数组的定义和使用教程(二)

    Java中数组的定义和使用教程(二)

    这篇文章主要给大家介绍了关于Java中数组的定义和使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01

最新评论