详解如何给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应用添加插件机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot项目里面发起http请求的几种方法

    SpringBoot项目里面发起http请求的几种方法

    Spring Boot发起HTTP请求有多种方法,包括:RestTemplate,WebClient, HttpClient, Feign Client,第三方库如OkHttp和Apache HttpClient,下面就来详细的介绍一下如何实现,感兴趣的可以了解一下
    2025-12-12
  • idea使用tomcat报404的问题及解决过程

    idea使用tomcat报404的问题及解决过程

    解决Tomcat部署问题:检查路径是否正确(JSP文件避免放在WEB-INF)、确保Tomcat配置路径一致,必要时重新部署,若日志乱码,修改logging.properties中编码为GBK
    2025-08-08
  • Java中的静态内部类详解及代码示例

    Java中的静态内部类详解及代码示例

    这篇文章主要介绍了Java中的静态内部类详解及代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • Java实现获取前、后N天日期的函数分享

    Java实现获取前、后N天日期的函数分享

    本文给大家分享的是使用java实现的获取当前日期前后N天的函数,非常的简单实用,有需要的小伙伴可以参考下。
    2015-03-03
  • Java使用OpenCV3.2实现视频读取与播放

    Java使用OpenCV3.2实现视频读取与播放

    这篇文章主要为大家详细介绍了Java使用OpenCV3.2实现视频读取与播放,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 使用Spring Boot框架整合Redis的超详细案例教程

    使用Spring Boot框架整合Redis的超详细案例教程

    本文详细介绍了如何在SpringBoot项目中整合Redis,包括依赖配置、连接设置、基本操作和应用案例,通过整合,可以充分利用SpringBoot和Redis的优势,提升应用性能和可扩展性,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • springboot如何配置多kafka

    springboot如何配置多kafka

    这篇文章主要介绍了springboot如何配置多kafka问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • IDEA配置Java类方法注释模板实践

    IDEA配置Java类方法注释模板实践

    这篇文章主要介绍了IDEA配置Java类方法注释模板实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-03-03
  • 浅谈java中的重载和重写的区别

    浅谈java中的重载和重写的区别

    本文主要介绍了java中的重载和重写的区别。具有一定的参考价值,下面跟着小编一起来看下吧,希望能够给你带来帮助
    2021-11-11
  • Java用 Gradle配置compile及implementation和api的区别

    Java用 Gradle配置compile及implementation和api的区别

    这篇文章主要介绍了Java用Gradle配置compile及implementation和api的区别,文章围绕主题的相关资料展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-06-06

最新评论