enable作为模块驱动在Spring Farmework、Spring Boot、Spring Cloud使用,都是通过注解的形式以@enable作为前缀,一些常用注解如
  
    
       
  
  框架 
      注解 
      模块 
    
如何自定义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();
  }
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。
