详解如何给Sprintboot应用添加插件机制

 更新时间:2023年08月25日 09:19:51   作者:陈sir的知识库  
这篇文章主要为大家介绍了如何给 Sprintboot 应用添加插件机制,文中有详细的解决方案及示例代码,具有一定的参考价值,需要的朋友可以参考下

场景

想要让boot应用增加插件能力,扩展restful api。插件可以由第三方开发

要解决的问题

  • 第三方的api需要和主应用使用相同的pom依赖
  • 第三方的api独立打包成jar包,并按照命名规则取名
  • 第三方的api需要再boot应用之外的独立存储中放置(部署)
  • 第三方的api jar 包的加载时机及方式

方案

  • 独立的依赖管理 pom 第三方插件继承此pom 统一依赖
  • api jar 包放置到特定路径。由boot 启动时加载。(也可以热加载,但实现方式复杂一些)
  • 技术点 classloader 加载插件 jar, 类型需要添加到spring bean 中统一管理生命周期。

下面是classloader的实现

public class ClassLoaderUtil {
    public static ClassLoader getClassLoader(String url) {
        try {
            Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            if (!method.isAccessible()) {
                method.setAccessible(true);
            }
            URLClassLoader classLoader = new URLClassLoader(new URL[]{}, ClassLoader.getSystemClassLoader());
            method.invoke(classLoader, new URL(url));
            return classLoader;
        } catch (Exception e) {
            log.error("getClassLoader-error", e);
            return null;
        }
    }
}

启动时将类加入到spring中

public class PluginImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    private final String targetUrl = "file:/D:/SpringBootPluginTest/plugins/plugin-impl-0.0.1-SNAPSHOT.jar";
    private final String pluginClass = "com.plugin.impl.PluginImpl";
    @SneakyThrows
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        ClassLoader classLoader = ClassLoaderUtil.getClassLoader(targetUrl);
        Class<?> clazz = classLoader.loadClass(pluginClass);
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        BeanDefinition beanDefinition = builder.getBeanDefinition();
        registry.registerBeanDefinition(clazz.getName(), beanDefinition);
    }
}

运行时将类加载到spring中,此时需要用ApplicationContextAware

@Component
public class SpringUtil implements ApplicationContextAware {
    private DefaultListableBeanFactory defaultListableBeanFactory;
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;
        this.defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
    }
    public void registerBean(String beanName, Class<?> clazz) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getRawBeanDefinition());
    }
    public Object getBean(String name) {
        return applicationContext.getBean(name);
    }
}

做一个运行时加载的入口

@GetMapping("/reload")
public Object reload() throws ClassNotFoundException {
		ClassLoader classLoader = ClassLoaderUtil.getClassLoader(targetUrl);
		Class<?> clazz = classLoader.loadClass(pluginClass);
		springUtil.registerBean(clazz.getName(), clazz);
		PluginInterface plugin = (PluginInterface)springUtil.getBean(clazz.getName());
		return plugin.sayHello("test reload");

到此这篇关于详解如何给Sprintboot应用添加插件机制的文章就介绍到这了,更多相关Sprintboot应用添加插件机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringSecurity的防Csrf攻击实现代码解析

    SpringSecurity的防Csrf攻击实现代码解析

    这篇文章主要介绍了SpringSecurity的防Csrf攻击实现代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java IO异常如何处理详析

    Java IO异常如何处理详析

    异常就是Java程序在运行过程中出现的错误,下面这篇文章主要给大家介绍了关于Java IO异常如何处理的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • 23种设计模式(4) java生成器模式

    23种设计模式(4) java生成器模式

    这篇文章主要为大家详细介绍了23种设计模式之java生成器模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • SpringCloud集成Sleuth和Zipkin的思路讲解

    SpringCloud集成Sleuth和Zipkin的思路讲解

    Zipkin 是 Twitter 的一个开源项目,它基于 Google Dapper 实现,它致力于收集服务的定时数据,以及解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现,这篇文章主要介绍了SpringCloud集成Sleuth和Zipkin,需要的朋友可以参考下
    2022-11-11
  • JAVA十大排序算法之桶排序详解

    JAVA十大排序算法之桶排序详解

    这篇文章主要介绍了java中的桶排序,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • servlet的常见注册方式总结

    servlet的常见注册方式总结

    servlet大家都不陌生,当开发 Web 应用程序时,注册 Servlet 是一个常见的任务,本文将介绍一些常见的 Servlet 注册方法,希望对大家有所帮助
    2023-10-10
  • Spring的编程式事务和声明式事务详解

    Spring的编程式事务和声明式事务详解

    这篇文章主要介绍了Spring的编程式事务和声明式事务的相关内容,涉及Spring事务属性、Spring事务的基本类等知识,需要的朋友可以了解下。
    2017-09-09
  • SpringController返回值和异常自动包装的问题小结

    SpringController返回值和异常自动包装的问题小结

    今天遇到一个需求,在不改动原系统代码的情况下,将Controller的返回值和异常包装到一个统一的返回对象中去,下面通过本文给大家介绍SpringController返回值和异常自动包装的问题,需要的朋友可以参考下
    2024-03-03
  • Java 实战范例之精美网上音乐平台的实现

    Java 实战范例之精美网上音乐平台的实现

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+vue+Springboot+ssm+mysql+maven+redis实现一个前后端分离的精美网上音乐平台,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • maven打包所有依赖对外提供sdk.jar

    maven打包所有依赖对外提供sdk.jar

    这篇文章主要介绍了maven打包所有依赖,对外提供sdk.jar,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06

最新评论