国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JSP > 正文

學習Tomcat動態加載JSP的Class類

2019-11-14 23:29:20
字體:
來源:轉載
供稿:網友
學習Tomcat動態加載jsp的Class類

今天在修改項目一個JSP文件時,突然想到Tomat是怎么實現動態實時加載JSP編譯后的class類的?

查了半天資料,看了很多文章,終于明白是怎么回事了:ClassLoader,當tomcat發現jsp改變后,將用新的ClassLoader去加載新的類

具體原理我將單獨總結一下,這里簡單實現了動態加載類

1.定義服務類

public class Servlet {    public void service(){        System.out.

2.定義服務線程

public class ServiceThread extends Thread{    public void run(){        try {            ClassLoader classLoader = this.getContextClassLoader();            Class clazz = classLoader.loadClass("Servlet");            Method service = clazz.getMethod("service", null);            service.invoke(clazz.newInstance(), null);        } catch (Exception e) {            e.printStackTrace();        }    }}

3.自定義ClassLoader

public class MyClassLoader extends ClassLoader{    @Override    public Class loadClass(String name, boolean resolve) throws ClassNotFoundException{        try {                        // 我們要創建的Class對象            Class clasz = null;            // 必需的步驟1:如果類已經在系統緩沖之中            // 我們不必再次裝入它            clasz = findLoadedClass(name);            if (clasz != null)                return clasz;            try {                // 讀取經過加密的類文件                if(name.equals("Servlet")){            //加載class文件字節                    byte classData[] = Util.readFile(ProgramPathHelper.getProgramPath()+"/"+name + ".class");                    if (classData != null) {                        // ... 再把它轉換成一個類                        clasz = defineClass(name, classData, 0,                                classData.length);                    }                }                            } catch (Exception e) {                e.printStackTrace();            }                        // 必需的步驟2:如果上面沒有成功            // 我們嘗試用默認的ClassLoader裝入它            if (clasz == null)                clasz = findSystemClass(name);            // 必需的步驟3:如有必要,則裝入相關的類            if (resolve && clasz != null)                resolveClass(clasz);            // 把類返回給調用者            return clasz;        } catch (Exception ie) {            throw new ClassNotFoundException(ie.toString());        }     }}

4.實現文件監聽類

public class CCFileListener implements FileAlterationListener{    public static HashMap<String,ClassLoader> claMap = new HashMap<String, ClassLoader>();        ZJPFileMonitor monitor = null;    @Override    public void onStart(FileAlterationObserver observer) {        //System.out.println("onStart");    }    @Override    public void onDirectoryCreate(File directory) {        System.out.println("onDirectoryCreate:" +  directory.getName());    }    @Override    public void onDirectoryChange(File directory) {        System.out.println("onDirectoryChange:" + directory.getName());    }    @Override    public void onDirectoryDelete(File directory) {        System.out.println("onDirectoryDelete:" + directory.getName());    }    @Override    public void onFileCreate(File file) {        System.out.println("onFileCreate:" + file.getName());        dyncLoadClass(file.getName());    }    @Override    public void onFileChange(File file) {     //文件改變處理函數        System.out.println("onFileChange : " + file.getName());                dyncLoadClass(file.getName());            }        private void dyncLoadClass(String className){        if(className.contains("Servlet")){//            ZJPFileMonitor.thread.setContextClassLoader(new MyClassLoader());            claMap.put(className, new MyClassLoader());        }    }    @Override    public void onFileDelete(File file) {        System.out.println("onFileDelete :" + file.getName());    }    @Override    public void onStop(FileAlterationObserver observer) {        //System.out.println("onStop");    }}
public class CCFileMonitor {            FileAlterationMonitor monitor = null;    public CCFileMonitor(long interval) throws Exception {        monitor = new FileAlterationMonitor(interval);    }    public void monitor(String path, FileAlterationListener listener) {        FileAlterationObserver observer = new FileAlterationObserver(new File(path));        monitor.addObserver(observer);        observer.addListener(listener);    }    public void stop() throws Exception{        monitor.stop();    }    public void start() throws Exception {        monitor.start();    }    public static void main(String[] args) throws Exception {        CCFileMonitor m = new CCFileMonitor(5000);        m.monitor(ProgramPathHelper.getProgramPath(),new CCFileListener());        m.start();                Servlet servlet = new Servlet();        servlet.service();        MyClassLoader defaultCl = new MyClassLoader();        while(true){                        Thread.currentThread().sleep(3000);                            Thread t = new ServiceThread();                //設置新線程的類加載器                ClassLoader classLoader = CCFileListener.claMap.get("Servlet.class");                if(classLoader==null){                    classLoader = defaultCl;                }                                t.setContextClassLoader(classLoader);                t.start();                            }        }}
public static HashMap<String,ClassLoader> claMap = new HashMap<String, ClassLoader>();在監聽到文件改變后,依據類名重new一個類加載器,用于加載類。
 ClassLoader classLoader = CCFileListener.claMap.get("Servlet.class");
if(classLoader==null){   classLoader = defaultCl;}
 首先獲取類名對應的加載器,如果沒有使用默認的加載器
 ClassLoader classLoader = this.getContextClassLoader(); Class clazz = classLoader.loadClass("Servlet"); Method service = clazz.getMethod("service", null); service.invoke(clazz.newInstance(), null);在線程內部使用剛才在外部設置的線程上下文加載器加載新的Servlet,并執行

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 象山县| 阳江市| 锦屏县| 资阳市| 宜章县| 报价| 清徐县| 尚志市| 柯坪县| 大同市| 龙海市| 台中县| 新泰市| 凤台县| 砚山县| 河北省| 高碑店市| 台北县| 虞城县| 岑巩县| 平江县| 铜陵市| 佛坪县| 合江县| 沂水县| 城固县| 垣曲县| 长沙市| 金湖县| 岳阳县| 株洲市| 彭泽县| 红河县| 阿拉尔市| 蓝田县| 乌拉特中旗| 正安县| 利川市| 涡阳县| 永嘉县| 阜宁县|