使用自动生成java文件和自动编译的动态代理模式

[java]  view plain copy
  1. /* 
  2.  * 接口中有几个方法,那么使用反射的getMethods()就会有几个方法名 
  3.  * 因为接口是不会继承Object的 
  4.  */  
  5. public interface Moveable {  
  6.     void move();//  
  7. }  
[java]  view plain copy
  1. public class Car implements Moveable{  
  2.     @Override  
  3.     public void move() {  
  4.         System.out.println("我是卡车,出发开往目的地...");  
  5.     }  
  6. }  

[java]  view plain copy
  1. public interface UserMgr {  
  2.     void addUser();  
  3. }  
[java]  view plain copy
  1. public class UserMgrImpl implements UserMgr {  
  2.     @Override  
  3.     public void addUser() {  
  4.         System.out.println("1: 插入记录到user表");  
  5.         System.out.println("2: 做日志在另外一张表");  
  6.     }  
  7. }  
[java]  view plain copy
  1. //作为动态代理的预设框架,把需要增加的内容放入事先写好的功能中  
  2. public interface InvocationHandler {  
  3.     /** 
  4.      * @param obj 要代理类的对象car 
  5.      * @param method 要代理类的对象car的代理方法 
  6.      */  
  7.     void invoke(Object obj,Method method);  
  8. }  

[java]  view plain copy
  1. //对要代理类的对象的方法进行运行时间长短的测量  
  2. public class TimerInvocation implements InvocationHandler{  
  3.     //target是要代理的对象,在客户端创建TimeInvocation时就进行传递  
  4.     //为什么不在下面的invoke里直接传递obj为要代理的对象呢?  
  5.     //那是因为在Proxy1类中要创建一个临时的代理对象$Proxy,然后这个$Proxy  
  6.     //的对象会会调用这个TimerInvocation中的invoke方法,这个时候无法传递真  
  7.     //正的要代理的对象,使用反射也不行,因为反射只会创建一个新的实例,而非一  
  8.     //个拥有某种属性或功能的对象,故只能在客户端中进行传递  
  9.     private Object target;  
  10.       
  11.     public TimerInvocation(Object target){  
  12.         this.target=target;  
  13.     }  
  14.       
  15.     //method是要代理的对象的方法  
  16.     //这里的obj暂时没起到作用  
  17.     @Override  
  18.     public void invoke(Object obj, Method method) {  
  19.         System.out.println("开始进行运行时间测量...");  
  20.         long start=System.currentTimeMillis();  
  21.         try {  
  22.             method.invoke(target);  
  23.         } catch (Exception e) {  
  24.             e.printStackTrace();  
  25.         }   
  26.         System.out.println("共耗费时间:"+(System.currentTimeMillis()-start));  
  27.     }  
  28.   
  29. }  

[java]  view plain copy
  1. public class TransactionHandler implements InvocationHandler {  
  2.       
  3.     private Object target;  
  4.       
  5.     public TransactionHandler(Object target) {  
  6.         super();  
  7.         this.target = target;  
  8.     }  
  9.   
  10.     @Override  
  11.     public void invoke(Object o, Method m) {  
  12.         System.out.println("Transaction Start");  
  13.         try {  
  14.             m.invoke(target);  
  15.         } catch (Exception e) {  
  16.             e.printStackTrace();  
  17.         }  
  18.         System.out.println("Transaction Commit");  
  19.     }  
  20.   
  21. }  

[java]  view plain copy
  1. public class Proxy1 {  
  2.     /** 
  3.      *  
  4.      * @param interfa 这个就是Moveable接口的class 
  5.      * @param h 告诉Proxy类要产生的是什么类型的代理,可以是时间代理,日志代理 
  6.      * 也就是要对interfa里的方法实现什么样的代理或功能 
  7.      * @return 
  8.      * 思路: 
  9.      * 生成一个临时的代理类$Proxy,这个类继承于Moveable接口 
  10.      * 这个类要去调用InvacationHandler的子类的invoke方法,实现切面的功能 
  11.      * 然后返回这个临时代理类的对象,并让得到这个代理类的对象调用move()方法即可 
  12.      */  
  13.     public static Object newProxyInstance(Class interfa,InvocationHandler h)throws Exception{  
  14.         String rt="\r\n";  
  15.         String java="package proxy1.dynamic;" +  rt ;  
  16.               java+="import java.lang.reflect.Method;" + rt ;  
  17.               java+="public class $Proxy implements "+interfa.getName() +"{" + rt;  
  18.               java+="   private InvocationHandler hand;" + rt;  
  19.               java+="   public $Proxy(InvocationHandler hand){" + rt;  
  20.               java+="       this.hand=hand;" + rt;  
  21.               java+="   }" + rt;  
  22.                 
  23.               Method[] methods=interfa.getMethods();  
  24.               for(Method method : methods){//对接口interfa中的方法进行实现  
  25.                   java+="   @Override" + rt;  
  26.                   java+="   public void "+method.getName()+"(){" + rt;  
  27.                   java+="       try{" + rt;                 
  28.                       java+="       Method m="+interfa.getName()+".class.getMethod(\""+method.getName()+"\");" + rt;  
  29.                       java+="       hand.invoke(this,m);" + rt;  
  30.                       java+="   }catch(Exception e){e.printStackTrace();}" + rt;          
  31.                   java+="   }" + rt;  
  32.               }  
  33.               java+="}" + rt;  
  34.               System.out.println(java);  
  35.         //创建java文件  
  36.           String filepath=System.getProperty("user.dir")+"/src/proxy1/dynamic";  
  37.           File file=new File(filepath+"/$Proxy.java");  
  38.           try{  
  39.             file.createNewFile();  
  40.             FileWriter fw=new FileWriter(file);  
  41.             fw.write(java);  
  42.             fw.close();   
  43.           }catch(Exception e){e.printStackTrace();}  
  44.         //编译  
  45.             JavaCompiler javac=ToolProvider.getSystemJavaCompiler();  
  46.             StandardJavaFileManager javafile=javac.getStandardFileManager(nullnullnull);  
  47.             String filename=filepath+"/$Proxy.java";  
  48.             Iterable units=javafile.getJavaFileObjects(filename);  
  49.             CompilationTask t=javac.getTask(null, javafile, nullnullnull, units);  
  50.             t.call();  
  51.             try {javafile.close();  
  52.             } catch (IOException e) {e.printStackTrace();}  
  53.         //把刚才在D:/下生成的class文件CarTimeProxy.class加载进内存并生成实例对象  
  54.         URL[] urls;  
  55.         Object obj=null;  
  56.         try {  
  57.             urls = new URL[]{new URL("file:///D:/Workspaces/base/bin/")};  
  58.             URLClassLoader classload=new URLClassLoader(urls);  
  59.             Class clazz=classload.loadClass("proxy1.dynamic.$Proxy");  
  60.             Constructor cons=clazz.getConstructor(InvocationHandler.class);  
  61.             obj=cons.newInstance(h);  
  62.         } catch (Exception e) {  
  63.             e.printStackTrace();  
  64.         }   
  65.         return obj;  
  66.           
  67.     }  
  68. }  

[java]  view plain copy
  1. public class Client {  
  2.     public static void main(String[] args) throws Exception {  
  3.           
  4.         /*Moveable move=new Car(); 
  5.         Moveable proxy=(Moveable) Proxy.newProxyInstance(move); 
  6.         proxy.move();*/  
  7.         /*Moveable move=new Car(); 
  8.         InvocationHandler hand=new TimerInvocation(move); 
  9.         Moveable proxy=(Moveable)Proxy1.newProxyInstance(Moveable.class, hand); 
  10.         proxy.move();*/  
  11.         UserMgr mgr = new UserMgrImpl();  
  12.         InvocationHandler h = new TransactionHandler(mgr);//先对日志进行捕获  
  13.         UserMgr u = (UserMgr)Proxy1.newProxyInstance(UserMgr.class,h);  
  14.         InvocationHandler h2 = new TimerInvocation(u);//再对时间进行测量  
  15.         UserMgr u1 = (UserMgr)Proxy1.newProxyInstance(UserMgr.class,h2);  
  16.         u1.addUser();  
  17.         /** 
  18.          * 运行结果: 
  19.          * 开始进行运行时间测量... 
  20.          * Transaction Start 
  21.          * 1: 插入记录到user表 
  22.          * 2: 做日志在另外一张表 
  23.          * Transaction Commit 
  24.          * 共耗费时间:0 
  25.          */  
  26.     }  
  27. }  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值