JDK動態代理實現原理

JDK動態代理實現原理思路:

1. 聲明一段源碼,這段源碼動態生成咱們的動態代理;

//一、聲明一段源碼,動態產生代理
//windows系統中的回車換行符\r\n
String rt = "\r\n";
String methodStr="";
for(Method m : infce.getMethods()) {
    methodStr += "    @Override"+rt+
    " public void " + m.getName() +"() {"++
    " try{"+rt+
    " Method md = "+infce.getName+".class.getMethod(\""+m.getName()+"\""+rt+
    " h.invoke(this,md);"+rt+
    " }catch(Exception e){e.printStackTra();}"+rt+
"}";
}

String str=
"package com.imooc.proxy;"+rt+
"import java.lang.reflect.Method;"+rt+
"import com.imooc.proxy.InvocationHandler+rt+
"public class $Proxy0 implements+infce.getName()+ " {"+rt+
"    public $Proxy0(InvocationHandler h) +rt+
"    this.h = h;"+rt+
"}"+rt+
" private InvocationHandler h;"+rt+
methodStr+rt+
"}";

2. 把源碼生成Java文件;

//產生代理類的Java文件
String filename = System.getProperty("user.dir")+"/bin/com/imooc/proxy/$Proxy0.java";
File file = new File(filename);
FileUtils.writeStringToFile(file, str);

3. 獲取系統的Java編譯器(JavaCompiler相似與javac);

JavaCompiler comproiler = ToolProvider.getSystemJavaCompiler();

4. 獲取文件管理器StandardJavaFileManager;

StandardJavaFileManager fileManager = comproiler.getStandardFileManager(null, null, null);

5. 獲取須要編譯的java文件對象(Iterable);

Iterable units = fileManager.getJavaFileObjects(file);

6. 獲取編譯的任務();

CompilationTask task = comproiler.getTask(null, fileManager, null, null, null, units);

7. 進行編譯;

task.call();

8. 關閉文件管理器

fileManager.close();

9. 編譯完成後會生成class文件;

10. 把class文件加載到內存中;

//由於生成的文件在bin目錄下,能夠直接使用ClassLoader進行加載
ClassLoader cl = ClassLoader.getSystemClassLoader();
//默認生成的代理類名稱均爲 $Proxy0
Class c = cl.loadClass("com.imooc.proxy.$Proxy0");

11. 產生一個代理類的對象,並返回該對象;

//獲取類的構造函數,建立類的實例
Constructor ctr = c.getConstructor(InvocationHandler.class);
return ctr.newInstance(h);

12. 代理類的調用

建立一個InvocationHandler(專門作事務處理)java

Car car = new Car();
InvocationHandler h = new TimeHandler(car);
Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class,h);
m.move();
相關文章
相關標籤/搜索