欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Springboot基于enable模块驱动的实现

程序员文章站 2023-11-09 14:16:46
enable作为模块驱动在spring farmework、spring boot、spring cloud使用,都是通过注解的形式以@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();
  }

}

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