java强大的反射机制给动态代理带来了可能、能够自由穿梭在类与方法之间、简直神通广大、
动态代理的一个小例子,顺便看看神奇的AOP是如何实现的、代码如下:
首先声明的是一个接口Dog类
1 package com.chenjun.test; 2 3 public interface Dog 4 { 5 public void info(); 6 public void run(); 7 }
然后一个“猎狗类”实现了该接口
1 package com.chenjun.test; 2 3 public class GunDog implements Dog 4 { 5 6 @Override 7 public void info() 8 { 9 // TODO 自动生成的方法存根 10 System.out.println("猎狗"); 11 } 12 13 @Override 14 public void run() 15 { 16 // TODO 自动生成的方法存根 17 System.out.println("迅速奔跑"); 18 } 19 20 }
然后是一个用于切面编程的AOP类,比如在鬣狗类的方法执行前后分别调用method1和method2
代码如下:
1 package com.chenjun.test; 2 3 public class DogAop 4 { 5 6 public void method1() 7 { 8 System.out.println(" AOP method1"); 9 } 10 public void method2() 11 { 12 System.out.println(" AOP method2"); 13 } 14 15 }
然后本例的最重要的一个类登场:
AOP将实际target调用的方法无情夹杀、 形成所谓的AOP
1 /** 2 * 3 */ 4 package com.chenjun.test; 5 6 import java.lang.reflect.InvocationHandler; 7 import java.lang.reflect.Method; 8 9 /** 10 * @author Administrator 11 * 12 */ 13 public class MyInvocationHandle implements InvocationHandler 14 { 15 //需要被代理的对象 16 /* (非 Javadoc) 17 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) 18 */ 19 private Object target; //需要被代理的目标对象 20 public void setTarget(Object target) 21 { 22 this.target = target; //设置需要被代理的目标对象 23 } 24 public Object invoke(Object proxy, Method method, Object[] args) //开始代理了。挂羊头卖狗肉开始 25 throws Throwable 26 { 27 // TODO 自动生成的方法存根 28 DogAop dogAop = new DogAop(); //用于AOP的类实例化 29 dogAop.method1(); //AOP方法1 30 Object result = method.invoke(target, args); //真实的方法调用。利用反射 31 dogAop.method2(); //aop方法2 32 33 return result; 34 } 35 36 }
最后来个主函数:
1 package com.chenjun.test; 2 3 import java.lang.reflect.Proxy; 4 5 public class Main 6 { 7 public static void main(String []args) 8 { 9 Dog target = new GunDog(); //new一个需要被动态代理的对象 10 MyInvocationHandle handler = new MyInvocationHandle(); 11 handler.setTarget(target); //挂羊头卖狗肉开始 12 13 Dog dog = (Dog)Proxy.newProxyInstance(target.getClass().getClassLoader(), 14 target.getClass().getInterfaces(), 15 handler); 16 dog.info(); //明修栈道,暗度陈仓 ,内部已经调用了代理类的方法。原对象的方法被添油加醋了、 17 dog.run(); //同上 18 } 19 }