大家好,又见面了,我是你们的朋友全栈君。
今天发现早年在大象笔记中写的一篇笔记,之前放在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>
http://commons.apache.org/proper/commons-vfs/
。这里,我们继承其FileListener接口,实现
fileChanged
即可:
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();
}
}
}
https://github.com/chenjie19891104/ijavaboy/tree/master/AppLoader,欢迎下载使用,你拥有一切的权利对其进行修改。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143499.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...