首页 > 编程 > Java > 正文

Springboot基于enable模块驱动的实现

2019-11-26 08:39:24
字体:
来源:转载
供稿:网友

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表