<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 188,comments - 176,trackbacks - 0
    定制類加載器

      

        要較好地控制類的加載,就要實現定制的類加載器。所有自定義的類加載器都應繼承自java.lang.ClassLoader。而且在構造方法中,我們也應該設置父類加載器。然后重寫findClass()方法。differentversionspush文件夾包含了一個叫做FileSystemClassLoader的自訂制的類加載器。其結構如圖9所示。

      圖9. 定制類加載器關系

      以下是在common.FileSystemClassLoader實現的主方法:

    public byte[] findClassBytes(String className){

            try{
                String pathName = currentRoot +
                    File.separatorChar + className.
                    replace('.', File.separatorChar)
                    + ".class";
                FileInputStream inFile = new
                    FileInputStream(pathName);
                byte[] classBytes = new
                    byte[inFile.available()];
                inFile.read(classBytes);
                return classBytes;
            }
            catch (java.io.IOException ioEx){
                return null;
            }
        }

        public Class findClass(String name)throws
            ClassNotFoundException{

            byte[] classBytes = findClassBytes(name);
            if (classBytes==null){
                throw new ClassNotFoundException();
            }
            else{
                return defineClass(name, classBytes,
                    0, classBytes.length);
            }
        }

        public Class findClass(String name, byte[]
            classBytes)throws ClassNotFoundException{

            if (classBytes==null){
                throw new ClassNotFoundException(
                    "(classBytes==null)");
            }
            else{
                return defineClass(name, classBytes,
                    0, classBytes.length);
            }
        }

        public void execute(String codeName,
            byte[] code){

            Class klass = null;
            try{
                klass = findClass(codeName, code);
                TaskIntf task = (TaskIntf)
                    klass.newInstance();
                task.execute();
            }
            catch(Exception exception){
                exception.printStackTrace();
            }
        }

      這個類供客戶端把client.TaskImpl(v1)轉換成字節數組,之后此字節數組被發送到RMI服務端。在服務端,一個同樣的類用來把字節數組的內容轉換回代碼??蛻舳舜a如下:

    public class Client{

        public static void main (String[] args){

            try{
                byte[] code = getClassDefinition
                    ("client.TaskImpl");
                serverIntf.execute("client.TaskImpl",
                    code);
                }
                catch(RemoteException remoteException){
                    remoteException.printStackTrace();
                }
            }

        private static byte[] getClassDefinition
            (String codeName){
            String userDir = System.getProperties().
                getProperty("BytePath");
            FileSystemClassLoader fscl1 = null;

            try{
                fscl1 = new FileSystemClassLoader
                    (userDir);
            }
            catch(FileNotFoundException
                fileNotFoundException){
                fileNotFoundException.printStackTrace();
            }
            return fscl1.findClassBytes(codeName);
        }
    }

      在執行引擎中,從客戶端收到的代碼被送到定制的類加載器中。定制的類加載器把其從字節數組定義成類,實例化并執行。需要指出的是,對每一個客戶請求,我們用類FileSystemClassLoader的不同實例來定義客戶端提交的client.TaskImpl。而且,client.TaskImpl并不在服務端的類路徑中。這也就意味著當我們在FileSystemClassLoader調用findClass()方法時,findClass()調用內在的defineClass()方法。類client.TaskImpl被特定的類加載器實例所定義。因此,當FileSystemClassLoader的一個新的實例被使用,類又被重新定義為字節數組。因此,對每個客戶端請求類client.TaskImpl被多次定義,我們就可以在相同執行引擎JVM中執行不同的client.TaskImpl的代碼。

    public void execute(String codeName, byte[] code)throws RemoteException{

            FileSystemClassLoader fileSystemClassLoader = null;

            try{
                fileSystemClassLoader = new FileSystemClassLoader();
                fileSystemClassLoader.execute(codeName, code);
            }
            catch(Exception exception){
                throw new RemoteException(exception.getMessage());
            }
        }

      示例在differentversionspush文件夾下。服務端和客戶端的控制臺界面分別如圖10,11,12所示:

      圖10. 定制類加載器執行引擎

      圖10顯示的是定制的類加載器控制臺。我們可以看到client.TaskImpl的代碼被多次加載。實際上針對每一個客戶端,類都被加載并初始化。

      圖11. 定制類加載器,客戶端1

      圖11中,含有client.TaskImpl.class.getClassLoader(v1)的日志記錄的類TaskImpl的代碼被客戶端的VM加載,然后送到服務端。圖12 另一個客戶端把包含有client.TaskImpl.class.getClassLoader(v1)的類代碼加載并送往服務端。

      圖12. 定制類加載器,客戶端1

      這段代碼演示了我們如何利用不同的類加載器實例來在同一個VM上執行不同版本的代碼。

      J2EE的類加載器

      J2EE的服務器傾向于以一定間隔頻率,丟棄原有的類并重新載入新的類。在某些情況下會這樣執行,而有些情況則不。同樣,對于一個web服務器如果要丟棄一個servlet實例,可能是服務器管理員的手動操作,也可能是此實例長時間未相應。當一個JSP頁面被首次請求,容器會把此JSP頁面翻譯成一個具有特定形式的servlet代碼。一旦servlet代碼被創建,容器就會把這個servlet翻譯成class文件等待被使用。對于提交給容器的每次請求,容器都會首先檢查這個JSP文件是否剛被修改過。是的話就重新翻譯此文件,這可以確保每次的請求都是及時更新的。企業級的部署方案以.ear, .war, .rar等形式的文件,同樣需要重復加載,可能是隨意的也可能是依照某種配置方案定期執行。對所有的這些情況——類的加載、卸載、重新加載……全部都是建立在我們控制應用服務器的類加載機制的基礎上的。實現這些需要擴展的類加載器,它可以執行由其自身所定義的類。Brett Peterson已經在他的文章 Understanding J2EE Application Server Class Loading Architectures給出了J2EE應用服務器的類加載方案的詳細說明,詳見網站TheServerSide.com。

      結要

      本文探討了類載入到虛擬機是如何進行唯一標識的,以及類如果存在同樣的類名和包名時所產生的問題。因為沒有一個直接可用的類版本管理機制,所以如果我們要按自己的意愿來加載類時,需要自己訂制類加載器來擴展其行為。我們可以利用許多J2EE服務器所提供的“熱部署”功能來重新加載一個新版本的類,而不改動服務器的VM。即使不涉及應用服務器,我們也可以利用定制類加載器來控制java應用程序載入類時的具體行為。Ted Neward的書Server-Based Java Programming中詳細闡述java的類加載,J2EE的API以及使用他們的最佳途徑。

    posted on 2007-05-24 10:56 cheng 閱讀(366) 評論(0)  編輯  收藏 所屬分類: JBS
    主站蜘蛛池模板: 大桥未久亚洲无av码在线| 久久九九全国免费| 精品亚洲视频在线观看| 伊人免费在线观看高清版| 亚洲韩国在线一卡二卡| 四虎www免费人成| 91视频精品全国免费观看| 亚洲av无码片在线观看| 成人伊人亚洲人综合网站222| a毛片免费观看完整| 亚洲乱色伦图片区小说| 国产亚洲精品a在线无码| 97人伦色伦成人免费视频| 国产午夜精品理论片免费观看| 亚洲一欧洲中文字幕在线| 国产综合精品久久亚洲| 成人免费毛片内射美女APP | 在线免费视频你懂的| 亚洲国产一区在线观看| 亚洲成a人片在线播放| 国产高清不卡免费在线| fc2成年免费共享视频网站| 亚洲一区在线视频| 亚洲尤码不卡AV麻豆| 中文字幕久久亚洲一区| 成人免费无码大片a毛片软件 | 亚洲综合一区二区精品久久| 高清在线亚洲精品国产二区| AA免费观看的1000部电影| 99久久精品毛片免费播放| 国产亚洲精品美女2020久久| 色偷偷亚洲女人天堂观看欧| 久久国产亚洲精品麻豆| 亚洲福利精品一区二区三区| 成年女人18级毛片毛片免费| 一级特黄aa毛片免费观看| 99久久免费国产精精品| 一级毛片一级毛片免费毛片| 亚洲AV女人18毛片水真多| 亚洲妇女熟BBW| 亚洲综合偷自成人网第页色|