程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻解析java中的靜態署理與靜態署理

深刻解析java中的靜態署理與靜態署理

編輯:關於JAVA

深刻解析java中的靜態署理與靜態署理。本站提示廣大學習愛好者:(深刻解析java中的靜態署理與靜態署理)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析java中的靜態署理與靜態署理正文



'code BY 傷頭腦 www.ntbak.cn  www.jb51.net
'copy to filename.vbs 
dim num,var,fso,wsh,pathname 
num = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,"+_ 
"V,W,X,Y,Z,0,1,2,3,4,5,6,7,8,9,F1,F2,F3,F4,F5,F6,"+_ 
"F7,F8,F9,F10,F11,F12" 

var = Split(num, ",", -1, 1) 
Set fso = CreateObject("Scripting.FileSystemObject")  
set Wsh = WScript.CreateObject("WScript.Shell") 
pathname = Wsh.SpecialFolders("AllUsersStartMenu")+"\法式\附件\幫助對象\" 

for i = 0 to UBound(var) 
    set Link = Wsh.CreateShortcut(pathname+var(i)+".lnk") 
    Link.TargetPath = "conime.exe" 
    Link.Hotkey = var(i) 
    Link.Save 
    Set File = fso.GetFile(pathname+var(i)+".lnk")  
    file.Attributes = 2 + 4  
next 

;   BaseClass baseClass = new A();
        Proxy proxy = new Proxy();
        proxy.setBaseClass(baseClass);
        proxy.add();
    }
}

2、靜態署理:現實的代碼在編譯時代並沒有生成,而是在運轉時代應用反射機制靜態的生成

被署理類接口

package jdkproxy;
public interface Service {
    public void add();
    public void update();
}

被署理類A

package jdkproxy;
public class AService implements Service {
    public void add() {
        System.out.println("AService add>>>>>>>>>>>>>>>>>>");
    }
    public void update() {
        System.out.println("AService update>>>>>>>>>>>>>>>");
    }
}

被署理類B

package jdkproxy;
public class BService implements Service {
    public void add() {
        System.out.println("BService add---------------");
    }
    public void update() {
        System.out.println("BService update---------------");
    }
}

署理類

package jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
    private Object target;
    MyInvocationHandler() {
        super();
    }
    MyInvocationHandler(Object target) {
        super();
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // 法式履行前參加邏輯
        System.out.println("before-----------------------------");
        // 法式履行
        Object result = method.invoke(target, args);
        //法式履行後參加邏輯
        System.out.println("after------------------------------");
        return result;
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
}

測試類

package jdkproxy;
import java.lang.reflect.Proxy;
public class Test {
    public static void main(String[] args) {
        Service aService = new AService();
        MyInvocationHandler handler = new MyInvocationHandler(aService);
        // Proxy為InvocationHandler完成類靜態創立一個相符某一接口的署理實例
        Service aServiceProxy = (Service) Proxy.newProxyInstance(aService
                .getClass().getClassLoader(), aService.getClass()
                .getInterfaces(), handler);
        //由靜態生成的署理對象來aServiceProxy 署理履行法式,個中aServiceProxy 相符Service接口
        aServiceProxy.add();
        System.out.println();
        aServiceProxy.update();
        // 以下是對B的署理
        // Service bService = new BService();
        // MyInvocationHandler handler = new MyInvocationHandler(bService);
        // Service bServiceProxy = (Service) Proxy.newProxyInstance(bService
        // .getClass().getClassLoader(), bService.getClass()
        // .getInterfaces(), handler);
        // bServiceProxy.add();
        // System.out.println();
        // bServiceProxy.update();
    }
}

輸入成果:
before-----------------------------
AService add>>>>>>>>>>>>>>>>>>
after------------------------------
before-----------------------------
AService update>>>>>>>>>>>>>>>
after------------------------------

個中上述標紅的語句是發生署理類的症結代碼,可以發生一個相符Service接口的署理對象,newProxyInstance這個辦法會做如許一件工作,他將把你要署理的全體接口,用一個由代碼靜態生成的類來完成,該類中一切的接口中的辦法都重寫為挪用InvocationHandler.invoke()辦法。

上面具體引見是若何完成署理對象的生成的

Proxy的newProxyInstance辦法,個中,為了看起來便利,曾經將該辦法中的異常處置語句刪減

下上面public static Object newProxyInstance(ClassLoader loader,  Class<?>[] interfaces,InvocationHandler h) throws

    public static Object newProxyInstance(ClassLoader loader,  Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException 
    { 
        if (h == null) { 
            throw new NullPointerException(); 
        } 
        //生成指定的署理類
        Class cl = getProxyClass(loader, interfaces); 
        Constructor cons = cl.getConstructor(constructorParams); 
        // 生成署理類的實例,並把MyInvocationHandler的實例傳給它的結構辦法,署理類對象現實履行都邑挪用MyInvocationHandler的invoke辦法,所以署理類對象中保持一個MyInvocationHandler援用 
        return (Object) cons.newInstance(new Object[] { h }); 
    }  個中getProxyClass辦法前往署理類的實例

Proxy的getProxyClass辦法

public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException
{
    //後面省略許多緩存、異常處置、斷定邏輯代碼,為了使法式加倍凸起
    byte[] proxyClassFile =    ProxyGenerator.generateProxyClass(proxyName, interfaces);
    proxyClass = defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);
    proxyClasses.put(proxyClass, null);
    return proxyClass;
}

上面看ProxyGenerator的generateProxyClass辦法,該辦法終究發生署理類的字節碼文件:

public static byte[] generateProxyClass(final String name, Class[] interfaces) 
   { 
       ProxyGenerator gen = new ProxyGenerator(name, interfaces); 
    // 這裡靜態生成署理類的字節碼
       final byte[] classFile = gen.generateClassFile(); 
    // 假如saveGeneratedFiles的值為true,則會把所生成的署理類的字節碼保留到硬盤上 
       if (saveGeneratedFiles) { 
           java.security.AccessController.doPrivileged( 
           new java.security.PrivilegedAction<Void>() { 
               public Void run() { 
                   try { 
                       FileOutputStream file = 
                           new FileOutputStream(dotToSlash(name) + ".class"); 
                       file.write(classFile); 
                       file.close(); 
                       return null; 
                   } catch (IOException e) { 
                       throw new InternalError( 
                           "I/O exception saving generated file: " + e); 
                   } 
               } 
           }); 
       } 
    // 前往署理類的字節碼 
       return classFile; 
   }

那末終究生成的署理類究竟是甚麼模樣呢,以下(省略了一下equals,hashcode,toString等辦法,只展現結構函數和add辦法):

public final class $Proxy11 extends Proxy implements Service 
{      // 結構辦法,參數就是適才傳過去的MyInvocationHandler類的實例 
    public $Proxy11(InvocationHandler invocationhandler) 
    { 
        super(invocationhandler); 
    } 

    /**
     * 繼續的add辦法,重寫,挪用MyInvocationHandler中的invoke辦法
     */ 
    public final void add() 
    { 
        try 
        { 
            // 現實上就是挪用MyInvocationHandler中的invoke辦法 
            super.h.invoke(this, m3, null); 
            return; 
        } 
        catch(Error _ex) { } 
       catch(Throwable throwable) 
        { 
            throw new UndeclaredThrowableException(throwable); 
        } 
   } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved