原 JPress技术精讲:JPress如何做到安装后重新加载的?
2960 | 0 | 0
JFinal应用实战视频教程:http://www.roncoo.com/course/view/a44d3a2e82614a9e95497af07065ce71
JPress安装完成后,如何能重新加载?
简单回答下:
1、jetty模式下,JFinal会自动指定检查WebRoot目录,如果有发生变化,会自动重新加载。
2、tomcat容器下,可以通过tomcat的相关配置,让tomcat监控相应的文件,如果发生变化会自动重新加载。
下面简要通过代码来看下JFinal在jetty模式下如何做到重新加载的。
玩过JFinla的人都知道,JFinal有一个start方法,通过start方法来启动jetty服务,方便开发调试。代码如下:
public static void start(int port) {
JFinal.start("WebRoot", 8080, "/", 5);
}通过JFinal.start方法,传入相关的配置,即可启动jetty。
JFinal的start方法也非常简单,代码如下:
public final class JFinal { //....此处省略
public static void start() {
server = ServerFactory.getServer();
server.start();
} //....此处省略}通过ServerFactory.getServer()获取一个Server,然后启动Server。这里获取的Server是一个jettyServer。代码如下:
class JettyServer implements IServer { // ...此处省略
public void start() { if (!running) { try {doStart();} catch (Exception e) {LogKit.error(e.getMessage(), e);}
running = true;
}
} private void doStart() { // ...此处省略
Scanner scanner = new Scanner(PathKit.getRootClassPath(), scanIntervalSeconds) { public void onChange() { try {
System.err.println("\nLoading changes ......");
webApp.stop();
JFinalClassLoader loader = new JFinalClassLoader(webApp, getClassPath());
webApp.setClassLoader(loader);
webApp.start();
System.err.println("Loading complete.");
} catch (Exception e) {
System.err.println("Error reconfiguring/restarting webapp after change in watched files");
LogKit.error(e.getMessage(), e);
}
}
};
scanner.start();
}
// ...此处省略
} // ...此处省略}
当Server调用start方法后,start方法会调用doStart()方法,doStart()里面创建了一个扫描器Scanner,传入一个匿名内部类,实现监听onChange监听,并调用Scanner.start()启动Scanner。
Scanner的简要代码如下:
public abstract class Scanner { public void start() { if (!running) {
timer = new Timer("JFinal-Scanner", true);
task = new TimerTask() {public void run() {working();}};
timer.schedule(task, 1010L * interval, 1010L * interval);
running = true;
}
} private void working() {
scan(rootDir);
compare();
preScan.clear();
preScan.putAll(curScan);
curScan.clear();
}
private void scan(File file) { if (file == null || !file.exists()) return ;
if (file.isFile()) { try {
curScan.put(file.getCanonicalPath(), new TimeSize(file.lastModified(),file.length()));
} catch (IOException e) {
LogKit.error(e.getMessage(), e);
}
} else if (file.isDirectory()) {
File[] fs = file.listFiles(); if (fs != null) for (File f : fs)
scan(f);
}
}
private void compare() { if (preScan.size() == 0) return;
if (!preScan.equals(curScan))
onChange();
}
}当Scanner的start方法被调用的时候,会启动一个定时器执行working()方法,working()方法内部只做两件事情。
1、通过scan方法扫描文件,并把文件的最后修改时间添加到curScan这个map里面去。
2、通过compare方法来判断刚刚扫描的额这个map和之前已经的map是否相同,如果不相同就调用onChange()方法。
刚才我们在JettyServer传入了一个匿名内部类,并实现了onChange()方法了,因此,Scanner调用onChange其实就是调用了JettyServer传入的这个匿名内部类的onChange()。
再回头来看一下匿名内部类的onChange()的实现:
Scanner scanner = new Scanner(PathKit.getRootClassPath(), scanIntervalSeconds) { public void onChange() { try {
System.err.println("\nLoading changes ......");
webApp.stop();
JFinalClassLoader loader = new JFinalClassLoader(webApp, getClassPath());
webApp.setClassLoader(loader);
webApp.start();
System.err.println("Loading complete.");
} catch (Exception e) {
System.err.println("Error reconfiguring/restarting webapp after change in watched files");
LogKit.error(e.getMessage(), e);
}
}
};
在这里,我们能够很明显的看到,通过webApp.stop方法停止了web服务,然后又通过start()方法启动了web服务。
到此,Jetty环境下讲解完毕。我们也得到了这么一个结论:只要RootClassPath下有文件发生变化,就会造成jetty重新加载,JPress也是利用了JFinal的这个特性,安装完毕后会在ClassPath下创建db.properties文件,发生了文件变化,从而让Jetty达到重新加载的目的。
0

小飞
19人已关注
领课教育 32523
10318
update 47761
5151
领课教育 18470
husheng 21146
请更新代码 41832
凯哥Java 2422
凯哥Java 2849
凯哥Java 2149