深刻解析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
被署理類接口
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);
}
}
}