动态代理中有两个类:Proxy类:生成代理类
InvocationHandler接口:处理事务的
Proxy类通过,传入的接口的类类型创建一个代理类实现动态,那么它是如何创建的呢?
创建的步骤如下:
1.编写源码(代理类,实现继承接口)
2.编译源码
3.加载进内存,生成代理对象
4.返回代理对象
代码如下:
package com.imooc.proxy;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import org.apache.commons.io.FileUtils;
public class Proxy {
public static Object newProxyInstance(Class inface,InvocationHandler h) throws Exception{
String rt = "\r\n";
String methodstr = "";
//通过接口生成代理对象的方法
for(Method m:inface.getMethods()){
methodstr +=
" @Override"+rt+
" public void "+m.getName()+"() {"+rt+
" // TODO Auto-generated method stub"+rt+
" try{"+rt+
" Method md = "+inface.getName()+".class.getMethod(\""+m.getName()+"\");"+rt+
" h.invoke(this,md,null);"+rt+
" }catch(Exception e){e.printStackTrace();}"+rt+
" }"+rt;
}
//代理类
String proxyClass =
"package com.imooc.proxy;"+rt+
"import java.lang.reflect.Method;"+rt+
"public class $Proxy0 implements " + inface.getName()+ " {"+rt+
" private "+inface.getName()+" m;"+rt+
" private InvocationHandler h;"+rt+
" public $Proxy0( InvocationHandler h){"+rt+
" this.h = h;"+rt+
" }"+rt+
methodstr+rt+
" }"+rt;
//编写源代码
String filename = System.getProperty("user.dir")+"/bin/com/imooc/proxy/$Proxy0.java";
File file = new File(filename);
FileUtils.write(file, proxyClass);
System.out.println(filename);
//编译
//获得编译器
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//文件管理者
StandardJavaFileManager filemgr = compiler.getStandardFileManager(null, null, null);
//获取文件
Iterable units = filemgr.getJavaFileObjects(filename);
//获取编译任务
CompilationTask c = compiler.getTask(null, filemgr, null, null, null, units);
//编译
c.call();
filemgr.close();
//加载类
//获得加载器
ClassLoader cl = ClassLoader.getSystemClassLoader();
//加载
Class<?> cla = cl.loadClass("com.imooc.proxy.$Proxy0");
System.out.println(cla.getName());
//生成对象
//通过构造方法生成对象
Constructor cst = cla.getConstructor(InvocationHandler.class);
return cst.newInstance(h);
}
}
InvocationHandler:管理事务的,可以添加日志,花费时间等等事务
先声明一个接口类:
package com.imooc.proxy;
import java.lang.reflect.Method;
public interface InvocationHandler {
public Object invoke(Object obj,Method method,Object[] args);
}
然后实现具体事务,继承接口:
我这里是实现花费时间
package com.imooc.proxy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TimeHandler implements InvocationHandler {
private Object target;
public TimeHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object obj, Method method, Object[] args) {
// TODO Auto-generated method stub
try {
//添加事务--->时间
long start = System.currentTimeMillis();
//调用目标类的方法
method.invoke(target, args);
long end = System.currentTimeMillis();
System.out.println("生产的时间为:"+(end-start)+"毫秒");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
测试:
package com.imooc.proxy;
public class Test {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
LiningClothing lc = new LiningClothing();
InvocationHandler h = new TimeHandler(lc);
ClothingFactory lf = (ClothingFactory)Proxy.newProxyInstance(ClothingFactory.class,h);
lf.productClothing();
}
}
还有需要用的接口(被代理类的接口)和目标类(被代理的类)
package com.imooc.proxy;
public interface ClothingFactory {
public void productClothing();
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.imooc.proxy;
public class LiningClothing implements ClothingFactory {
@Override
public void productClothing() {
// TODO Auto-generated method stub
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
===========================================================
当生成的代理对象调用方法的流程: