加载

Spring提供了下面这些类来加载外部jar。

classPathResorce可以用来加载类路径上的jar。
一般推荐使用

            classLoader = new UrlClassLoader(new URL[] {resource.getURL()}, parentClassLoader);

来创建一个classLoader。其中parentClassLoader可以通过BeanClassLoaderAware从当前Spring上下文中拿到。
一般,我们会写一MyClassPathXmlApplicationContext继承ClassPathXmlApplicationContext。

    public MyClassPathXmlApplicationContext(String[] paths, ClassLoader classLoader, ApplicationContext parent)throws BeansException {super(parent);Assert.notNull(paths, "Path array must not be null");Assert.notNull(classLoader, "Class argument must not be null");this.classLoader = classLoader;this.configResources = new Resource[paths.length];for (int i = 0; i < paths.length; i++) {this.configResources[i] = new ClassPathResource(paths[i], classLoader);}}

我们主要是为了记录下当前的classLoader。和需要加载的Resource。同时也传入我们自己需要加载的配置文件。

parent的SpringContext可以通过ApplicationContextAware接口来拿到。
为了加载我们jar的内容,我们需要覆盖loadBeanDefinitions方法

@Overrideprotected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {// 使用系统cl先加载通用spring配置文件reader.setBeanClassLoader(Thread.currentThread().getContextClassLoader());String[] configLocations = getConfigLocations();if (configLocations != null) {reader.loadBeanDefinitions(configLocations);}// 使用决策jar对应的cl加载我们自己的配置文件reader.setBeanClassLoader(classLoader);// 加载决策jar中的指定URLif (configResources != null) {reader.loadBeanDefinitions(configResources);}}

我们自己实现的xml配置文件可以继承ComponentNamespaceHandler来解析。

        registerBeanDefinitionParser("gdl_tag", new GdlBeanDefinitionParser());

前面是xml节点,后面则是生成一个BeanDefinitionParser,可以用来生成一个BeanDefinition。
里面是经典的建造者模式,供Spring生成bean

public class AntMpsReaderComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {@Overrideprotected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {String bid = BeanDefinitionReaderUtils.getElementAttr(element, "id");BeanDefinitionBuilder builder = BeanDefinitionReaderUtils.getGenericBeanDefinition(parserContext, element, bid,GDL.class, true);// 注入builder.addPropertyValue("mpsServiceId", gdl1);builder.addPropertyValue("mpsVersion", gdl2);builder.addPropertyValue("mpsGroup", gdl3);builder.addPropertyValue("mpsParams", gdl4);return builder.getBeanDefinition();}}

卸载

既然可以加载,也必然必须能卸载。除了要卸载对象,必须也要把类加载也卸载掉。JVM判断类卸载的条件是

+ classLoader已经不存在
+ 该class的引用和实例已经不存在

我们会在后台循环尝试调用我的destroy方法

protected volatile     boolean            destroy            = false; //表示是否已经成功销毁protected volatile     boolean            init               = false;//表示是否已经初始化@Overridepublic void destroy() throws Exception {if (!init) {logger.warn("component[" + getId() + "] not initialized yet.");}if (!destroy) {synchronized (lock) {if (!destroy) {//其他销毁内容...if (classLoader != null) {//清除spring中因为内省锁保存的classLoaderclearClassLoaderCache(classLoader);//清除context中的所有bean。if (applicationContext != null && (applicationContext instanceof DisposableBean)) {((DisposableBean) applicationContext).destroy();}//将classLoader设置为null。classLoader = null;}destroy = true;logger.warn("decision unit[" + getId() + "] destroyed.");}}}}

其实上面的代码并不完美。一个简单的例子,如果加载一个极为复杂的jar。有如下情况。

  • 该jar有内部线程。导致线程堆栈中所持有的所有对象都无法被释放。
  • 该类通过一些操作,让自己的类被外部类引用

这些都要求我们在开发动态加载jar时,特别是引入第三方依赖时,仔细杜绝这些问题。

Spring实战之Spring动态加载jar模块和卸载模块相关推荐

  1. android动态jar,Android动态加载Jar(包含第三方依赖Jar)

    最近项目有一个需求,需要根据用户需求动态加载APP内某功能模块,且当该部分功能模块代码有变动,只需更新该功能JAR,无需更新整个APK,基于这个需求,决定采用动态加载Jar的方式去实现,于是各种查资料 ...

  2. java动态加载jar文件并执行方法

    在项目开发的过程中,有时候需要动态灵活的加载某个jar包并执行里面的方法的时候,我们可以使用本篇文章写得方式去动态的加载jar包而不用使用原始方式引入jar包作为lib去使用,接下来介绍如何动态加载j ...

  3. [转]Android动态加载jar/dex

    本文转自:http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html 前言 在目前的软硬件环境下,Native App与Web App ...

  4. flink sql udf jar包_Java动态加载Jar实例解析

    导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景.如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用.下面将举一个简 ...

  5. Java动态加载jar及class文件

    经常碰到需要动态加载jar及class文件的场景.Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 一.动态加载ja ...

  6. java动态加载jar时,jar中还有第三方jar无法加载的解决方法

    java动态加载jar时,jar中还有第三方jar无法加载的解决方法 当java插件化开发时,即一个java程序在运行的情况下动态加载另一个jar,网上大多数的方法如下 public static v ...

  7. 实战之jvm-sandbox动态加载插件实现

    在实际应用中,当我们某些功能点开发完成的时候,需要重启部署才能够让功能得到应用.但这个功能比较适合插件开发,将功能拆分成一个个独立的jar来提供功能点的拆组. ​ 简单场景 假设我们现在有发短信和发送 ...

  8. Android动态加载jar/dex

    http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html 加载jar boolean bool = new File("/ ...

  9. [转]动态加载jar文件

    本文转自:http://zhongzhao-2008.iteye.com/blog/201487 初学Java时教科书告诉我们,若要运行Java程序,必需为其设置环境变量.有时候为了实现某种功能(例如 ...

最新文章

  1. aspx页面中使用%= %的注意事项
  2. 使用CLI扩展和重新平衡Couchbase集群
  3. 《.NET最佳实践》与Ext JS/Touch的团队开发
  4. Java架构师面试题系列之Mybatis面试专题(36题,含详细答案解析)
  5. CTS(5)---Android8.0中CTS测试对于TEE的要求
  6. vue 花括号里面的变量_二、Vue条件指令
  7. [渝粤教育] 西南科技大学 作物生产新理论与新技术 在线考试复习资料
  8. 2018-10-10 在浏览器插件中读取JSON资源文件
  9. C/C++深度分析(二)
  10. CODING Pages 服务全面升级,更快更稳更可靠!
  11. 手机电脑同屏_把手游变成端游的同屏神器,就是这款Onebit“X9”了!
  12. 嵌入式C语言面试题库
  13. 网易花19亿买地,要在上海建总部大楼,团队至少2000人
  14. art-illumina模拟测序
  15. 力扣(LeetCode)159. 至多包含两个不同字符的最长子串(2022.06.08)
  16. 寻路机器人单片机程序示例_单片机典型案例开发(四)
  17. 在办公室给智能手机充电怎么做最安全
  18. 通过cmd命令,获取当前文件夹下所有的文件的绝对路径,并存储在指定目录的文件夹中
  19. 备忘录 | 阅读而已,用得着这么认真么?
  20. 深度推荐模型 - DIN

热门文章

  1. 乐高ev3搭建图_乐高EV3摩天轮搭建说明,适合摆在前台吸引小朋友
  2. python+stata
  3. 戴尔Dell Latitude E6410/E6510官方拆机图解维修手册
  4. Texlive 2021+Sublime 3+SumatraPDF 不常见问题
  5. 水利行业来了新成员:【智慧水务防灾监测报警系统】工作模式更简单
  6. 基于C++的递归下降语法分析设计原理与实现
  7. Ubuntu文件管理命令
  8. 服务器同步/异步通知参数说明 (支付宝)
  9. VAE与GAN的关系(2)
  10. 基于JAVA图书馆座位预约管理系统服务端计算机毕业设计源码+数据库+lw文档+系统+部署