设计模式(一) 动态代理初尝试
程序员文章站
2022-04-09 19:00:09
摘要 之前老是听说动态代理,一直没有机会好好看过,现在就把动态代理的实现逻辑和用处整理一下。首先提两个概念,委托类和代理类。委托类就是实际业务逻辑的处理者,代理类是处于请求发起者与委托类之间的角色,所有对委托类的请求都会经过代理类。就是委托类将请求处理委托给代理类,代理类可以起到方法拦截、功能增强的 ......
- 摘要
之前老是听说动态代理,一直没有机会好好看过,现在就把动态代理的实现逻辑和用处整理一下。
首先提两个概念,委托类和代理类。委托类就是实际业务逻辑的处理者,代理类是处于请求发起者与委托类之间的角色,所有对委托类的请求都会经过代理类。
就是委托类将请求处理委托给代理类,代理类可以起到方法拦截、功能增强的作用。
实现动态代理的方式有很多,现在主流的主要jdk和cglib这两个。下面就用示例代码说明下动态代理的过程,以及用动态代理实现拦截器。 - 用jdk实现动态代理
jdk实现动态代理的包是java.lang.reflect.*,jdk实现动态代理有限制,委托类必须要实现接口,所以先要创建一个接口public interface myinterface { //jdk public void tes1(); //cglib public void test2(string val); }
创建接口实现类public class mytarget implements myinterface { //jdk @override public void tes1() { system.out.println("委托类业务处理!"); } //cglib @override public void test2(string val) { system.out.println("业务处理结果:"+val); } }
动态代理逻辑代码package proxy; import java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.proxy; public class myproxytest implements invocationhandler { //继承invocationhandler,拦截方法 private object target=null; //构造函数 public myproxytest(object target){ this.target = target ; } //获取代理类的方法 public static object getproxy(object target){ //通过proxy创建代理类,需要三个参数,委托类的类加载器、委托类实现的接口、代理类 /** * 这是jdk的动态代理模式,必须要有接口 * proxy会把代理类挂载到所有接口下面 * 如果委托类没有实现任何接口会有问题,改用cglib的enhancer增强类做动态代理 */ return proxy.newproxyinstance(target.getclass().getclassloader(), target.getclass().getinterfaces(),new myproxytest(target)); } //拦截方法 @override public object invoke(object proxy, method method, object[] args) throws throwable { system.out.println("进入代理逻辑!"); system.out.println("代理类处理逻辑!"); object result=null; result = method.invoke(target,args); system.out.println("委托类处理完后的逻辑!"); return result; } }
getproxy方法就是绑定委托类和代理类之间关系的方法,这里绑定的代理类是this当前对象,也就是myproxytest 的实例对象,由于实现了invocationhandler接口,所以在方法调用之前都会
通过invoke方法,在这里就可以写功能增强的代码。method.invoke(target,args)是通过反射运行委托类的方法。
测试用例public class junittest { public static void main(string[] args) { /** * jdk动态代理 */ system.out.println("---------jdk动态代理--------"); //委托类 mytarget target = new mytarget(); //给委托类绑定代理类 myinterface proxy = (myinterface)myproxytest.getproxy(target); proxy.tes1(); } }
运行结果---------jdk动态代理-------- 进入代理逻辑! 代理类处理逻辑! 委托类业务处理! 委托类处理完后的逻辑!
我们发现进入了代理类的处理逻辑。
- cglib实现动态代理
cglib实现动态代理和jdk大同小异,不过cglib是通过创建增强类enhancer,并且设置enhancer的委托类和代理类来实现动态代理。cglib的委托类不需要实现接口。
动态代理逻辑package proxy; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodinterceptor; import org.springframework.cglib.proxy.methodproxy; import java.lang.reflect.method; public class mycglibproxy implements methodinterceptor { public object getproxy(class target){ //创建增强类 enhancer enhancer = new enhancer(); //设置委托类 enhancer.setsuperclass(target); //设置代理类 enhancer.setcallback(this); return enhancer.create(); } @override public object intercept(object o, method method, object[] objects, methodproxy methodproxy) throws throwable { system.out.println("进入代理逻辑!"); system.out.println("代理类处理逻辑!"); object result=null; result = methodproxy.invokesuper(o,objects); system.out.println("委托类处理完后的逻辑!"); return result; } }
这里的getproxy接收的不是委托类的实例对象而是委托类。代理类是this,mycglibproxy 的实例对象,由于实现了methodinterceptor拦截器,所以方法调用都会经过intercept。
测试用例package proxy; public class junittest { public static void main(string[] args) { /** * cglib动态代理 */ system.out.println("---------cglib动态代理--------"); mycglibproxy cglib = new mycglibproxy(); myinterface cglibproxy = (myinterface)cglib.getproxy(mytarget.class); cglibproxy.test2("cglib动态代理"); } }
运行结果
---------cglib动态代理-------- 进入代理逻辑! 代理类处理逻辑! 业务处理结果:cglib动态代理 委托类处理完后的逻辑!
简单的实现动态代理的两种方式就完成了,之后再讲解拦截器和责任链模式
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
上一篇: 博客园美化