1.背景 对于Java游戏服务器来说,通常通过脚本运行jar执行。在开发测试环境下,需要经常打包、重新部署的需求,而往往重启服务器通常需要花费一定时间。而有了Spring-Loaded这个利器,直接替换运行的补丁jar,即可达到热更新功能.2.说明 目前官网上的release版本:springloaded-1.2.3.RELEASE.jar,并不支持reload jar这个功能,这个功能在1.2.4才开放。不过你可以git clone下源代码,用gradle build最新的jar:springloaded-1.2.4.BUILD-SNAPSHOT.jar。不过这个版本可能些许问题,即对我们的"windoze"支持不太友好,这个问题已经和其作者联系过了,最新github上的代码应该修复了。我是本地自己修改了一下(具体怎么修改的,可以参见我的博客中和作者的几封邮件),然后build的。当然如果你是mac或者是linux运行,则会完美运行。3.参数 -Dspringloaded=watchJars=foo.jar:bar.jar 即watchJars选项,监听的多个jar之前用:分离4.例子 有两个jar,一个spring-load-main.jar,一个spring-load-extra.jar,前者依赖后者,后者业务可能会经常变化,有热更新的需求。这里模拟一下线上环境,用脚本启动进程(windows),然后修改逻辑,重新打包,替换jar,看是否可以达到reload的目的 1.启动脚本:spring-loaded-example_launch.bat@echo off
cd /d %~dp0
java -noverify -javaagent:springloaded-1.2.4.BUILD-SNAPSHOT.jar -cp spring-load-main.jar;spring-load-extra.jar -Dspringloaded=verbose;explain;watchJars=spring-load-extra.jar com.mavsplus.example.springloaded.SpringLoadedExample2
说明:springloaded-1.2.4.BUILD-SNAPSHOT.jar/spring-load-main.jar/spring-load-extra.jar 这三个jar是在同一个目录."-javaagent"这个必须,指定agent为spring-loaded.通过-Dspringloaded=watchJars指定了监听的jar为spring-load-extra.jar,main类为SpringLoadedExample2 2.spring-loaded-main.jar只有一个类SpringLoadedExample2,spring-loadex-extra.jar也只有一个类Reloadpackage com.mavsplus.example.springloaded;
import java.util.concurrent.TimeUnit;
/**
* <a href="https://github.com/spring-projects/spring-loaded"></a>
*
* <pre>
* Spring Loaded allows you to add/modify/delete methods/fields/constructors.
* The annotations on types/methods/fields/constructors
* can also be modified and it is possible to add/remove/change values in enum types.
* </pre>
*
* @author landon
* @since 1.8.0_25
*/
public class SpringLoadedExample2 {
public static void main(String[] args) throws Exception {
Reload reload = new Reload();
while (true) {
reload.load();
TimeUnit.SECONDS.sleep(3);
}
}
} package com.mavsplus.example.springloaded;
/**
* 可reload的实现类
*
* @author landon
* @since 1.8.0_25
*/
public class Reload {
public void load() {
System.out.println("load");
}
}
3.运行启动脚本:spring-loaded-example_launch.batE:\github\mavsplus-all\mavsplus-examples\src\main\resources>spring-loaded-example_launch.batSL: [verbose mode on] Full configuration is:verbose;explain;watchJars=spring-load-extra.jarSL: [explain mode on] Reporting on the decision making process within SpringLoaded七月 01, 2015 8:25:16 下午 org.springsource.loaded.agent.SpringLoadedPreProcessor logPreProcessr logPreProcess信息: SpringLoaded preprocessing: classname=java/util/concurrent/TimeUnit$7 classloader=null typeRegistry=nullloadloadloadload 4.修改Reload.java,输出reload,然后重新打一个包并覆盖掉spring-load-extra.jar,这时候看到命令行输出:loadload七月 01, 2015 8:28:51 下午 org.springsource.loaded.agent.Watcher run信息: Observed last modification time change for e:\github\mavsplus-all\mavsplus-examples\src\main\resources\spring-load-extra.jar (lastScanTime=1435753730694)七月 01, 2015 8:28:51 下午 org.springsource.loaded.agent.Watcher determineChangesSince信息: Firing file changed event e:\github\mavsplus-all\mavsplus-examples\src\main\resources\spring-load-extra.jar七月 01, 2015 8:28:51 下午 org.springsource.loaded.agent.SpringLoadedPreProcessor logPreProcess信息: SpringLoaded preprocessing: classname=java/util/HashMap$KeyIterator classloader=null typeRegistry=null信息: SpringLoaded preprocessing: classname=java/io/ObjectStreamClass$Caches classloader=null typeRegistry=nullreloadreloadreloadreload 看上面红色部分,我们可以清楚的看到spring-loaded检测到了jar的时间戳的改变,并将其重新加载了,从输出我们可以看到5.总结: 通过该例子我们可以清楚的看到,用spring-loaded简直太幸福了。。直接替换jar包。。直接更新。。完美 相对比JRebel还需要指定一个monitor jar class jar。。简单多了。。具体对比可以参考我的上一篇随笔: http://www.blogjava.net/landon/archive/2015/06/26/425909.html
后续:会深入源代码以及更深层次的例子而不仅仅是直接替换方法body形式的热加载。。进行深入剖析
posted on 2015-07-01 20:40
landon 阅读(7728)
评论(2) 编辑 收藏 所属分类:
JVM 、
HotSwap