浏览 1744 次
锁定老帖子 主题:JAVA之JDK动态代理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2014-02-20
在Java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和接口,可以生成JDK动态代理类或动态代理对象。
Proxy提供了用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类,如果在程序中为一个或多个接口动态的生成实现类,就可以使用Proxy来创建动态代理类, 如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。 Proxy提供了如下两个方法,来创建动态代理类和动态代理实例。 getProxyClass(ClassLoader loader, Class<?>... interfaces) 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口,第一个ClassLoader参数指定生成动态代理类的类加载器。 newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 直接创建一个动态代理对象,该代理对象的实现类,实现了interfaces指定的系列接口,执行代理对象的每个方法都会被替换执行InvocationHandler对象的invoke方法。 实际上,即使采用第一个方法获取了一个动态代理类之后,当程序需要通过该代理类,来创建对象时一样,需要传入一个InvocationHandler对象,也就是说,系统生成的每个代理对象都有一个与之关联的的InvocationHandler对象。 代码演示: <pre name="code" class="java"> package com.qin.aop; /** * 通用的模拟AOP * 切面类,其方法可以在运行时被调入 * * **/ public class DogUtils { /** * * 第一个拦截器的方法 * * **/ public void method1(){ System.out.println("=======模拟第一个通用的方法=========="); } /** * * 第一个拦截器的方法 * * **/ public void method2(){ System.out.println("=======模拟第二个通用的方法=========="); } } </pre> Dog接口,JDK动态代理只能给接口生成代理。 <pre name="code" class="java">package com.qin.proxy; /*** * * 定义Dog接口 * */ public interface Dog { /** * * 详细信息的方法 * **/ public void info(); /** * 运行的方法 * * */ public void run(); } </pre> <pre name="code" class="java">package com.qin.proxy.impl; import com.qin.proxy.Dog; /** * * 实现类 * **/ public class GunDog implements Dog { @Override public void info() { System.out.println("我是一只猎狗! "); } @Override public void run() { System.out.println("我奔跑迅速!"); } } </pre> <pre name="code" class="java">package com.qin.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.qin.aop.DogUtils; /** * 动态代理的实现自定义类 * * * **/ public class MyInvokationHandler implements InvocationHandler{ /* * 需要被代理的对象 * **/ private Object obj; public void setObj(Object obj) { this.obj = obj; } /** * 执行动态代理对象的所有方法时, * 都会被替换成如下的invoke方法 * * ***/ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { DogUtils du=new DogUtils(); //执行DogUtils对象中的method1方法 du.method1(); //以target作为主调来执行method方法 Object result=method.invoke(obj, args); du.method2(); return result; } } </pre> <pre name="code" class="java">package com.qin.proxy; import java.lang.reflect.Proxy; /** * 该对象为指定的target生成动态代理实例 * * **/ public class MyProxyFactory { public static Object getProxy(Object obj){ //创建一个MyInvokationHandler对象 MyInvokationHandler hadler=new MyInvokationHandler(); hadler.setObj(obj); //创建并返回一个动态代理 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hadler); } } </pre> 测试: <pre name="code" class="java">package com.qin.test; import com.qin.proxy.Dog; import com.qin.proxy.MyProxyFactory; import com.qin.proxy.impl.GunDog; /** * * 测试驱动类 * **/ public class Test { public static void main(String[] args) { Dog target=new GunDog(); Dog dog=(Dog)MyProxyFactory.getProxy(target); dog.info(); dog.run(); } } </pre> 结果输出如下: <pre name="code" class="java">=======模拟第一个通用的方法========== 我是一只猎狗! =======模拟第二个通用的方法========== =======模拟第一个通用的方法========== 我奔跑迅速! =======模拟第二个通用的方法========== </pre> 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |