这是我的java项目的目录结构。
下边是我的一个项目的文件结构
依赖关系类似下图,中间的业务模块之间不相互依赖:
目前的问题是业务模块会持续增加,每个模块的开发不影响其他任何部分代码,所以我想的是,是否可以jvm启动一个主进程,主进程是一个springboot项目,只是没有各个业务模块的功能。然后各个业务模块可以以插件的形式动态加载和更新。
插件化架构在 Spring Boot 项目中是完全可行的,以下是实现思路的详细说明:
动态加载业务模块:
@Import
注解或 ApplicationContext
来动态加载业务模块。URLClassLoader
来加载外部 JAR 文件,并将其注册到 Spring 的上下文中。以下是一个简单的代码示例,展示如何动态加载一个 JAR 文件:
public void loadJar(String jarFilePath) throws Exception {
URL jarUrl = new File(jarFilePath).toURI().toURL();
URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
Class<?> clazz = classLoader.loadClass("com.example.YourPluginClass");
Object pluginInstance = clazz.getDeclaredConstructor().newInstance();
// 将插件实例注册到 Spring 上下文中
ApplicationContext context = ...; // 获取 Spring 上下文
((ConfigurableApplicationContext) context).getBeanFactory().registerSingleton("yourPluginBean", pluginInstance);
}
示例中,loadJar
方法可以动态加载指定路径的 JAR 文件,并将其中的类实例注册到 Spring 上下文中。可以实现业务模块的动态加载和卸载。
你说的应该是动态加载Jar包。Spring Boot提供了SpringBootClassLoader,它能够支持动态加载Jar包。
import org.springframework.boot.loader.JarLauncher;
public class DynamicLoading {
public static void main(String[] args) throws Exception {
JarLauncher launcher = new JarLauncher();
launcher.launch(args, new String[]{"com.example.MainClass"});
}
}
你也可以利用如OSGi等第三方库来实现更复杂的动态加载机制。
定义统一的插件接口,所有业务模块都需实现该接口。这样可以确保主应用程序能够与所有插件进行交互。在Spring Boot中,可以通过ApplicationContext在运行时注册新加载的Bean。
@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");
}
是的,Spring Boot 业务代码可以动态加载和更新。这通常可以通过使用 OSGi(Open Service Gateway initiative)或者 Spring 的模块化框架(如 Spring Boot DevTools、Spring Cloud 等)结合自定义类加载器来实现。然而,对于你描述的特定需求(即各个业务模块作为插件动态加载和更新),通常建议使用以下方案之一:
对于你的项目,如果业务模块之间的依赖关系简单且独立,并且你希望在生产环境中实现动态加载和更新,自定义类加载器或微服务架构可能是更合适的选择。如果你希望保持架构的简单性并愿意在开发过程中接受一些限制,Spring Boot DevTools 也是一个可行的选项。
请注意,动态加载和更新业务模块可能会引入一些额外的复杂性和挑战,如版本管理、安全性、事务处理等。因此,在实施之前,请仔细评估你的需求和限制,并选择最适合你项目的方案。
问题内容: 如标题所述,我想基于仅在运行时可用的信息来动态加载(或不)动态加载Go软件包。 目的是允许用户通过添加新的本机脚本命令的自定义程序包扩展程序。当前,每次我添加新命令或禁止使用某些命令时,都需要编辑程序并重新编译,而如果我可以制作某种dll之类的文件,则可以创建一个“导入”脚本命令来搜索和加载命名命令库。 出于好奇,该程序是基于定制命令的脚本库,我将其用于各种用途。 我提前进行了一些搜索
本文向大家介绍Java静态代码块加载驱动代码实例,包括了Java静态代码块加载驱动代码实例的使用技巧和注意事项,需要的朋友参考一下 Demo1.funx(); String s=Demo1.string; 静态代码块 会在new一个该类对象时调用 或者调用该类的静态方法,静态成员变量时调用 总之在类加载器将该类加载到内存中时 (无论是通过哪种方式) 都会调用静态代码块 静态成员变量 静态代码块永远
问题内容: 最后,我将开发环境从runserver迁移到gunicorn / nginx。 将runserver的自动重载功能复制到gunicorn会很方便,因此当源更改时,服务器会自动重新启动。否则,我必须使用手动重新启动服务器。 有什么办法可以避免手动重启? 问题答案: 尽管这是一个古老的问题,但仅出于一致性考虑-因为19.0版本的gunicorn可以–reload选择。因此,不再需要第三方工
提示: ●以Excel格式导出动态数据。 操作步骤: ①进入"业务动态"模块。 ②点击"动态下载",选择模板及日期范围进行下载。 操作动图: [查看原图]
问题内容: 最后,我将开发环境从runserver迁移到gunicorn / nginx。 将runserver的自动重载功能复制到gunicorn会很方便,因此当源更改时,服务器会自动重新启动。否则,我必须使用手动重新启动服务器。 有什么方法可以避免手动重启? 问题答案: 尽管这是一个老问题,但您需要知道自19.0版以来就可以选择。因此,现在不需要第三方工具。
本文向大家介绍一个简单的动态加载js和css的jquery代码,包括了一个简单的动态加载js和css的jquery代码的使用技巧和注意事项,需要的朋友参考一下 一个简单的动态加载js和css的jquery代码,用于在生成页面时通过js函数加载一些共通的js和css文件。 将该函数写入一个common.js文件中,在html中加载该common.js文件,就可以达到目的。 注意: 1.在html5中
问题内容: 我查找了语法并搜索了api,但仍然对该过程感到困惑。我还搜索了Stackoverflow。加载类并从中动态创建对象的正确方法是什么?换句话说,我希望用户指定要创建的对象类型,然后创建该类型的对象。我不需要菜单,因为我希望他们能够选择当前目录中的任何类。 问题答案: 假设该类具有无参数构造函数,则最简单的方法是- 参考-java.lang.Class
本文向大家介绍Android listview动态加载列表项实现代码,包括了Android listview动态加载列表项实现代码的使用技巧和注意事项,需要的朋友参考一下 最近了一个动态加载listview类表项的列子,分享出来大家学习学习,说说这个例子的实现过程,首先限定每次加载的列表项数据为10条数据,当拖动listview滚动到最后一条数据的时候再加载10条,并在Listview下方显示加载