JAVA的动态代理
代理模式 :
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
一、JDK动态代理:
直接使用JDK-API;
只能为实现了接口的类创建代理对象(通过接口形式创建对象)。
/**
* ①创建一个代理类JDKDynamicProxy实现InvocationHandler接口
* ②实现接口中的invoke方法
* ③在类中定义一个Object类型的属性,用来传递被代理对象
* ④提供一个带有Object类型的构造器
* ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象
*/
程序清单:
1.TestInterface接口
package com.softeem.dynamicproxy; public interface TestInterface { public void test01(); }
2.TestInterface实现接口
package com.softeem.dynamicproxy; public class TestImplement implements TestInterface { @Override public void test01() { System.out.println("这是JDK动态代理测试方法"); } }
3.JDK动态代理
package com.softeem.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 直接使用JDK-API * 只能为实现了接口的类创建代理对象(通过接口形式创建对象) * ①创建一个代理类JDKDynamicProxy实现InvocationHandler接口 * ②实现接口中的invoke方法 * ③在类中定义一个Object类型的属性,用来传递被代理对象 * ④提供一个带有Object类型的构造器 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象 */ public class JDKDynamicProxy implements InvocationHandler { private Object obj; public JDKDynamicProxy(Object obj) { this.obj = obj; } //获取代理对象 public Object getProxy(){ Object proxyObj = null; proxyObj = Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);//要绑定接口(这是一个缺陷,cglib弥补了这一缺陷) return proxyObj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("-------"); Object returnObj = method.invoke(obj, args); System.out.println("<><><><>"); return returnObj; } }
4.Test测试类
package com.softeem.dynamicproxy; public class Test { public static void main(String[] args) { TestImplement ti = new TestImplement(); //为ti对象创建代理对象 Object obj = new JDKDynamicProxy(ti).getProxy();//obj只存在于内存的对象 System.out.println(obj.getClass()); //因为jdk动态代理是通过接口创建的代理对象 TestInterface tif = (TestInterface) obj; //TestInterface tif2 = new TestImplement();父类引用指向子类对象(多态),不能调用子类特有的方法,只能调用抽象方法中的类 //通过代理对象调用方法时,实际上是调用类代理类中的invoke方法 tif.test01(); } }
二、cglib动态代理
使用到类第三方jar包:CDLib.jar
不能为final类创建代理对象(通过子类创建代理对象)
/**
* ①创建一个代理类CGLibDynamicProxy实现MethodInterceptor接口
* ②实现intercept方法
* ③在类中定义一个Object类型的属性,用来传递被代理对象
* ④提供一个带有Object类型的构造器
* ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象
*/
程序清单
1.cglib动态代理类CGLibDynamicProxy
package com.softeem.dynamicproxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用到类第三方jar包:CDLib.jar * 不能为final类创建代理对象(通过子类创建代理对象) * ①创建一个代理类CGLibDynamicProxy实现MethodInterceptor接口 * ②实现intercept方法 * ③在类中定义一个Object类型的属性,用来传递被代理对象 * ④提供一个带有Object类型的构造器 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象 */ public class CGLibDynamicProxy implements MethodInterceptor { private Object obj; public CGLibDynamicProxy(Object obj) { this.obj = obj; } public Object getProxy(){ //通过创建被代理对象的子类,来为其创建代理对象 Enhancer en = new Enhancer(); en.setSuperclass(obj.getClass()); en.setCallback(this);//回调 return en.create(); } @Override public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("-------"); Object returnObj = method.invoke(obj, arg2); System.out.println("<<><><><><>>"); return returnObj; } }
2.CGLibTest测试类
package com.softeem.dynamicproxy; public class CGLibTest { public static void main(String[] args) { TestImplement ti = new TestImplement(); CGLibDynamicProxy cgdp = new CGLibDynamicProxy(ti); //创建ti的代理对象obj Object obj = cgdp.getProxy(); //通过创建被代理对象类的子类来创建的代理对象 //所以可以讲代理对象直接强转成被代理对象的类型 TestImplement t = (TestImplement) obj; t.test01(); } }
本文出自 “黑足Sanji” 博客,谢绝转载!
原文地址:http://974124461.blog.51cto.com/8685015/1546310