之前已经写过一篇关于class的动态替换博客,今天我们来介绍一下如何用springloaded进行jar&class的动态替换。

首先说一下实验过程,结合了目前我正在做的项目,这个项目是一个前置系统,分别对接银联和核心系统。项目一开始由一个jar包组成,逻辑上可以分为3层:分发层,业务处理层,dao层(数据库操作相关),所有的class文件最后都在jar包中,运行时,只要启动这个jar包就行了,它是一个进程,会启动一个监听端口用来接收银联发送过来的报文。

这样做的缺点:后期你要修改代码,哪怕只有一行代码修改,你也要重新打包成jar包,kill掉正在运行的进程,然后重新启动!一开始对于我这种菜鸟,除了觉得这样做很麻烦之外,其他也没有觉得什么。后来,仔细一分析,在生产上运行,你停服务,是一件不可思议的事,因为所有的交易都要停止,像对于支付这样的交易,那影响就太大了!

所以,自然想到热部署方案,热部署网上也有一些相关的博客。但基本都不太“正规”,即都是那种简单的例子,看起来就不大可行。其中比较多的是自己定义classload来重新加载class文件,而且我看那些方法中路径和要重新加载的class文件都是写死的,这也太。。。当然,也有我觉得比较高大上的方法,就是将现在的系统改造成微服务架构,对于业务上独立的交易都改造成一个个微服务,那要卸载服务,重新部署服务自然都不在话下。不得不说,这确实是一个比较好的方法,但工作量和难度都是比较高的,想来想去,暂时不考虑,但会作为知识储备来学习,在适当的时间再来改造,因为这是趋势!

直到前几天,我偶然发现一个关于springloaded的帖子,这种方法比较简单,而且从名字可以看成,它是spring旗下的一个项目,应该来说还是比较可靠的,所以就试着用这个方法来进行改造,改造的方法也比较简单。

首先,我们要将jar包中的一些业务相关的代码从jar包中抽离出来,具体拆分的方法可以为,基本不需要修改的代码或者框架型的代码放在jar包中,而后期需要经常修改的代码从jar包冲分离出来。如下图:

所有的业务相关的代码(class文件)都放在business文件夹下,具体做法是创建了一个新的工程,然后现有的工程会依赖这个新的工程。同时,可以看到相关的配置文件我们也从jar包中分离出来,比如mybatis文件夹中放的是和数据库操作相关的文件。

我们在libs文件夹中放入

然后,输入命令:

这里插播一下,一开始我是上面这种写法,但是发现jar替换时不起任何效果,后来我想会不会是顺序的问题,我把-jar后面的参数移到最后面,发现这时候起作用了:

然后参数verbose可以省略,因为加上这个参数,日志中会有很多详细的信息,生产上不太方便查看,测试的时候可以加上。

我们发起一笔报文,前置系统运行结果如下:

我们对这个交易的代码进行修改,把“协议支付签约触发短信”这几个字去掉,然后保存,用这个class文件替换原先的class文件

可以看到,在不用停程序的情况下,运行结果已经改变了,基本达到我们的需求。

接下来的话就是,如果jar包里面的代码有修改,那就重新打包来替换旧的jar包,与替换class文件类似,我试了一下,同样是可以的。

2018-07-25更新

今天我在生产上试了一种情况,发现更换了class没有用,比如:a.jar直接调用了b.class,而b.class又调用了c.class,现在替换了c.class文件,发现不起作用。我们上面的例子是替换了b.class文件起作用。只有重启,c.class文件才起作用。这个问题后续值得继续关注!

利用springloaded进行java jar&class的动态替换的更多相关文章

  1. 利用springloaded进行java class动态替换

    我们知道对于一个java文件,如Test.java,首先需要通过javac命令(javac Test.java)进行编译,生成class文件,再将class文件在jvm上进行加载运行,也就是java命 ...

  2. 【java】 linux下利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...

  3. 使用C#利用cmd来调用java jar包获取其中的数据

    其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...

  4. java -jar参数运行方式设置classpath

    转载自:https://www.cnblogs.com/aggavara/archive/2012/11/16/2773246.html 当用java -jar yourJarExe.jar来运行一个 ...

  5. Java安全之Javassist动态编程

    Java安全之Javassist动态编程 0x00 前言 在调试CC2链前先来填补知识盲区,先来了解一下Javassist具体的作用.在CC2链会用到Javassist以及PriorityQueue来 ...

  6. 【hadoop2.6.0】利用Hadoop的 Java API

    Hadoop2.6.0的所有Java API都在 http://hadoop.apache.org/docs/r2.6.0/api/overview-summary.html 里. 下面实现一个利用J ...

  7. -Xbootclasspath参数、java -jar参数运行应用时classpath的设置方法

    当用java -jar yourJarExe.jar来运行一个经过打包的应用程序的时候,你会发现如何设置-classpath参数应用程序都找不到相应的第三方类,报ClassNotFound错误.实际上 ...

  8. 利用sfntly的sfnttool.jar提取中文字体

    雨忆博客中提到了sfntly(具体介绍可以看:https://code.google.com/p/sfntly/),利用其中sfnttool.jar就可以提取只包含指定字符的字体,如果想在页面中通过@ ...

  9. 【项目分析】利用C#改写JAVA中的Base64.DecodeBase64以及Inflater解码

    原文:[项目分析]利用C#改写JAVA中的Base64.DecodeBase64以及Inflater解码 最近正在进行项目服务的移植工作,即将JAVA服务的程序移植到DotNet平台中. 在JAVA程 ...

随机推荐

  1. spring boot通过Interceptor和HandlerMethodReturnValueHandler实现统一处理为controller返回对象统计处理时间

    思路:实现思路都是基于Aop实现,方式上可以通过spring aop和spring mvc的aop机制都能实现. 通过Interceptor的可以实现为controller插入开始时间和执行结束时间, ...

  2. 依赖、耦合、解耦、控制反转(IOC)、依赖注入(DI)

    随着net的深入学习,出现了很多概念性的东西需要理解,现在统一记录一下. 1.依赖:现阶段在任何一个有请求作用的系统,都会出现A类调用B类的情况,这时候A类就依赖于B类,A类和B类存在依赖关系. 2. ...

  3. python之路——14

    王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594 复习 1.迭代器 1.双下方法:不常直接调用,是通过其他语法触发的 2.可迭代的:可迭代协议——含有__it ...

  4. iframe-父子-兄弟页面相互传值(jq和js两种方法)

    参考文章: http://blog.csdn.net/u013299635/article/details/78773207 http://www.cnblogs.com/xyicheng/archi ...

  5. [UE4]添加手柄

    一.在上一节的VRPawnBase中,再添加2个Motion Controller,分别命名为:LeftMotionController.RightMotionController,分别代表左右手柄. ...

  6. minicom 抓取log

    使用minicom也有很长时间了,只用minicom抓过uart log,但是从来没有去保存过这个log,也不知道有这个功能.后来在超级终端中发现有这个功能(传送->捕获文字),想想minico ...

  7. 1 CRM

    一.crm介绍 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...

  8. Python3 复制和深浅copy

    赋值: 列表的赋值: list1 = ['peter','sam'] list2 = list1 print(list1,id(list1)) print(list2,id(list2)) list1 ...

  9. 通过scp拷贝文件时无需交互输入密码

    工作中经常需要把一些文件从一个服务器传输到另一台服务器,linux环境下最习惯的方式当然是scp,但是scp需要交互输入密码有时候觉得麻烦,记录几种无需手动输入密码的方法. 方法一:建立SSH互信 此 ...

  10. 使用jQuery+huandlebars遍历中if判断

    兼容ie8(很实用,复制过来,仅供技术参考,更详细内容请看源地址:http://www.cnblogs.com/iyangyuan/archive/2013/12/12/3471227.html) & ...