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 中 热部署与卸载关系的更多相关文章
- paip.提升用户体验--提升java的热部署热更新能力
paip.提升用户体验--提升java的热部署热更新能力 想让java做到php那么好的热部署能力 "fix online"/在线修复吗??直接在服务器上修改源码生效,无需重启应 ...
- java的热部署和热加载
ps:热部署和热加载其实是两个类似但不同的概念,之前理解不深,so,这篇文章重构了下. 一.热部署与热加载 在应用运行的时升级软件,无需重新启动的方式有两种,热部署和热加载. 对于Java应用程序来说 ...
- 计算机基础--Java中int char byte的关系
计算机基础--Java中int char byte的关系 重要:一个汉字占用2byte,Java中用char(0-65535 Unicode16)型字符来存字(直接打印输出的话是字而非数字),当然要用 ...
- JAVA代码热部署,在线不停服动态更新
本地debug的时候,可以实时编译并更新代码,线上也可以不停服来动态更新类,即所说的java热部署. JDK代理的两种方式: 1.premain方式是Java SE5开始就提供的代理方式,但其必须 ...
- Java服务器热部署的实现原理
转自:http://blog.csdn.net/chenjie19891104/article/details/42807959 在web应用开发或者游戏服务器开发的过程中,我们时时刻刻都在使用热部署 ...
- Java 项目热部署,节省构建时间的正确姿势
上周末,帮杨小邪(我的大学室友)远程调试项目.SpringBoot 构建,没有热部署,改一下就得重启相关模块.小小的 bug ,搞了我一个多小时,大部分时间都还在构建上(特么,下次得收钱才行).我跟他 ...
- java中接口与多重继承的关系
在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...
- spring-boot-devtools在Idea中热部署方法
1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.sprin ...
- SpringBoot热部署:spring-boot-devtools在Idea中热部署方法
1 pom.xml文件 注:热部署功能spring-boot-1.3开始有的 <!--添加依赖--> <dependency> <groupId>org.sprin ...
随机推荐
- php 创建返回结果配置文件 实例
<?phpclass validateReturn{ //get return msg function caseReturn($aRerurn) { $strM ...
- 潭州课堂25班:Ph201805201 django框架 第十二课 自定义中间件,上下文处理,admin后台 (课堂笔记)
中间件 在项目主目录下的配置文件 在项目主目录下创建文件 写个自定义异常处理 方法1 要让其生效,要在主目录下,的中间件中进行注册 主目录下.该文件名.类名 在进入视图函数之前进行判断, 给 req ...
- 潭州课堂25班:Ph201805201 爬虫高级 第十课 Scrapy-redis分布 (课堂笔记)
利用 redis 数据库,做 request 队列,去重,多台数据共享, scrapy 调度 基于文件每户,默认只能在单机运行, scrapy-redis 默认把数据放到 redis 中,实现数据共享 ...
- html网页中不能复制网站文字
使用下面的CSS属性 moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-sele ...
- U盘安装Ubuntu 14.04 LTS
1.下载Ubuntu14.04 LTS 从Ubuntu官网下载->http://releases.ubuntu.com/14.04/ 2.将Ubuntu14.04安装到U盘 下载U盘系统安装工具 ...
- 前端语言生成apk
https://www.cnblogs.com/softcg/p/6511030.html
- mysql三表查询sql语句
表结构: Student学生表(学号.姓名.性别.年龄.编辑) Course课程表(编号.课程名称) sc选课表(选课编号.学号.课程编号.成绩) (1)写一个SQL语句,查询选修了“计算机原理”的学 ...
- java第二周的学习知识4(对原码,补码,反码和java中浮点数计算不准确的总结)
原码:一个正数,转换为二进制位就是这个正数的原码.负数的绝对值转换成二进制位然后在高位补1就是这个负数的原码. 但是原码有几个缺点,零分两种 +0 和 -0 .很奇怪是吧!还有,在进行不同符号的加法运 ...
- 从MongoDB里面取得json格式的数据,然后存为本地的json文件,然后再从json读取变为dict
帮宣传下彩印网(www.caiyin.com) 有印刷,广告等等方面的需求就找这个网站吧,没错的. 天气预报在MongoDB中的天气预报的存储方式是: /* 1 */ { "_id" ...
- ASP.NET WebApi 基于分布式Session方式实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起学玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NETWebSer ...