Java热部署相关
今天发现早年在大象笔记中写的一篇笔记,之前放在ijavaboy上的,现在它已经访问不了了。前几天又有同事在讨论这个问题。这里拿来分享一下。
在web应用开发或者游戏服务器开发的过程中,我们时时刻刻都在使用热部署。热部署的目的很简单,就是为了节省应用开发和发布的时间。比如,我们在使用Tomcat或者Jboss等应用服务器开发应用时,我们经常会开启热部署功能。热部署,简单点来说,就是我们将打包好的应用直接替换掉原有的应用,不用关闭或者重启服务器,一切就是这么简单。那么,热部署到底是如何实现的呢?在本文中,我将写一个实例,这个实例就是一个容器应用,允许用户发布自己的应用,同时支持热部署。
- public interface IApplication {
- public void init();
- public void execute();
- public void destory();
- }
- public ClassLoader createClassLoader(ClassLoader parentClassLoader, String... folders) {
- List<URL> jarsToLoad = new ArrayList<URL>();
- for (String folder : folders) {
- List<String> jarPaths = scanJarFiles(folder);
- for (String jar : jarPaths) {
- try {
- File file = new File(jar);
- jarsToLoad.add(file.toURI().toURL());
- } catch (MalformedURLException e) {
- e.printStackTrace();
- }
- }
- }
- URL[] urls = new URL[jarsToLoad.size()];
- jarsToLoad.toArray(urls);
- return new URLClassLoader(urls, parentClassLoader);
- }
- <apps>
- <app>
- <name> TestApplication1</name >
- <file> com.ijavaboy.app.TestApplication1</file >
- </app>
- <app>
- <name> TestApplication2</name >
- <file> com.ijavaboy.app.TestApplication2</file >
- </app>
- </apps>
- public void createApplication(String basePath, AppConfig config){
- String folderName = basePath + GlobalSetting. JAR_FOLDER + config.getName();
- ClassLoader loader = this.jarLoader .createClassLoader(ApplicationManager. class.getClassLoader(), folderName);
- try {
- Class<?> appClass = loader. loadClass(config.getFile());
- IApplication app = (IApplication)appClass.newInstance();
- app.init();
- this.apps .put(config.getName(), app);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- public void loadAllApplications(String basePath){
- for(AppConfig config : this.configManager.getConfigs()){
- this.createApplication(basePath, config);
- }
- }
- public class TestApplication1 implements IApplication{
- @Override
- public void init() {
- System. out.println("TestApplication1-->init" );
- }
- @Override
- public void execute() {
- System. out.println("TestApplication1-->do something" );
- }
- @Override
- public void destory() {
- System. out.println("TestApplication1-->destoryed" );
- }
- }
- <app>
- <name> TestApplication1</name >
- <file> com.ijavaboy.app.TestApplication1</file >
- </app>
- public void fileChanged (FileChangeEvent event) throws Exception {
- String ext = event.getFile().getName().getExtension();
- if(!"jar" .equalsIgnoreCase(ext)){
- return;
- }
- String name = event.getFile().getName().getParent().getBaseName();
- ApplicationManager. getInstance().reloadApplication(name);
- public void reloadApplication (String name){
- IApplication oldApp = this.apps .remove(name);
- if(oldApp == null){
- return;
- }
- oldApp.destory(); //call the destroy method in the user's application
- AppConfig config = this.configManager .getConfig(name);
- if(config == null){
- return;
- }
- createApplication(getBasePath(), config);
- public void initMonitorForChange(String basePath){
- try {
- this.fileManager = VFS.getManager();
- File file = new File(basePath + GlobalSetting.JAR_FOLDER);
- FileObject monitoredDir = this.fileManager .resolveFile(file.getAbsolutePath());
- FileListener fileMonitorListener = new JarFileChangeListener();
- this.fileMonitor = new DefaultFileMonitor(fileMonitorListener);
- this.fileMonitor .setRecursive(true);
- this.fileMonitor .addFile(monitoredDir);
- this.fileMonitor .start();
- System. out.println("Now to listen " + monitoredDir.getName().getPath());
- } catch (FileSystemException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args){
- Thread t = new Thread(new Runnable() {
- @Override
- public void run() {
- ApplicationManager manager = ApplicationManager.getInstance();
- manager.init();
- }
- });
- t.start();
- while(true ){
- try {
- Thread. sleep(300);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
Java热部署相关的更多相关文章
- 揭秘Java热部署原理及JRebel(Hotcode)的实现原理
基础知识:class卸载.热替换和Tomcat的热部署的分析HotSwap:HotSwap和JRebel原理成熟的热部署技术实现原理:深入探索 Java 热部署 java的热部署和热加载
- 探秘 Java 热部署三(Java agent agentmain)
前言 让我们继续探秘 Java 热部署.在前文 探秘 Java 热部署二(Java agent premain)中,我们介绍了 Java agent premain.通过在main方法之前通过类似 A ...
- 探秘 Java 热部署二(Java agent premain)
# 前言 在前文 探秘 Java 热部署 中,我们通过在死循环中重复加载 ClassLoader 和 Class 文件实现了热部署的功能,但我们也指出了缺点-----不够灵活.需要手动修改文件等操作. ...
- JAVA热部署,通过agent进行代码增量热替换!!!
在前说明:好久没有更新博客了,这一年在公司做了好多事情,包括代码分析和热部署替换等黑科技,一直没有时间来进行落地写出一些一文章来,甚是可惜,趁着中午睡觉的时间补一篇介绍性的文章吧. 首先热部署的场景是 ...
- IntelliJ IDEA 的 Java 热部署插件 JRebel 安装及使用
JRebel 介绍 JRebel for Intellij JRebel 在 Java Web 开发中, 一般更新了 Java 文件后要手动重启 Tomcat 服务器, 才能生效, 自从有了 JRe ...
- 深入探索 Java 热部署
在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来 ...
- 深入探索 Java 热部署--转
在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.本文将探索如何在不破 ...
- Java 热部署深入探索
简介 在 Java 开发领域,热部署一直是一个难以解决的问题,目前的 Java 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的 ...
- 探索 Java 热部署
在 JAVA 开发领域,热部署一直是一个难以解决的问题,目前的 JAVA 虚拟机只能实现方法体的修改热部署,对于整个类的结构修改,仍然需要重启虚拟机,对类重新加载才能完成更新操作.对于某些大型的应用来 ...
随机推荐
- LG3275 【[SCOI2011]糖果】
前言 我对差分约束有我个人独特的看法,写这题解既是与大家分享,又算作我对差分约束系统的总结. 浅谈差分约束 对于一些给出形如\(x_i-x_j\leq a\)不等式(差分约束)组,求\(x_t-x_s ...
- hashCode()方法 和 hash()方法
String str = "abc"; String str1 = "abc"; System.out.println(str == str1); //true ...
- HotSpot VM GC 的种类
collector种类 GC在 HotSpot VM 5.0里有四种: incremental (sometimes called train) low pause collector已被废弃,不在介 ...
- hasura graphql-engine graphql2chartjs 方便的graphql 转换chartjs 的类库
graphql2chartjs 是hasura graphql-engine 团队开源的方便graphql 转换为chartjs 的类库,我们可以方便的 用来进行ChartJS chart 开发 一张 ...
- 线性代数及其应用 (David C.Lay, Steven R.Lay 著)
第1章 线性代数中的线性方程组 (已看) 介绍性实例 经济学与工程中的线性模型 1.1 线性方程组 1.2 行化简与阶梯形矩阵 1.3 向量方程 1.4 矩阵方程Ax=b 1.5 线性方程组的解集 1 ...
- 人教版高中数学(A版)
必修1 (已看) 第一章 集合与函数概念 1.1 集合 1.2 函数及其表示 1.3 函数的基本性质 第二章 基本初等函数(1) 2.1 指数函数 2.2 对数函数 2.3 幂函数 第三章 函数的应用 ...
- Array.asList()
package study.stage2;import java.util.*; /** * Created by Sandy.Liu on 2017/7/19. */public class Asl ...
- day7大纲
01 昨日内容回顾 数据类型补充: str <---> list split join list <---> set set(list) list(set()) list &l ...
- MINA线程模型
一.三种工作线程: (一) Acceptor thread: 该线程的作用是接收客户端的连接,并将客户端的连接导入到IOProcessor线程模型中.Acceptor thread在调用了Accep ...
- 设置Redis最大占用内存
https://blog.csdn.net/happyrabbit456/article/details/54945667 Redis需要设置最大占用内存吗?如果Redis内存使用超出了设置的最大值会 ...