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 ...