代理模式是对象的结构模式,代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
在代理模式中的介绍如下:
1)抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
2)目标对象角色:定义了代理对象所代表的目标对象。
3)代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。
举例如逢年过节加班比较忙没有时间去买火车票,打电话给附近的票务中心叫他们帮忙代购;但是票务中心并非卖票的,只有火车站才是真正出售票的地点,票务中心其实是通过火车站实现的。
1. 静态代理
接口(或抽象类),具体代码如下:
package com.yoodb; public interface Business { public void doAction(); }
此处是真正意义上实现业务逻辑的类,具体代码如下:
package com.yoodb; public class BusinessImpl implements Business { @Override public void doAction() { // TODO Auto-generated method stub System.out.println("实现业务逻辑."); } }
自己并未实现业务逻辑接口,而是调用实现,具体代码如下:
package com.yoodb; public class BusinessImplProxy implements Business{ private BusinessImpl impl; @Override public void doAction() { // TODO Auto-generated method stub if(impl == null){ impl = new BusinessImpl(); } doBefore(); impl.doAction(); doAfter(); } private void doBefore(){ System.out.println("调用目标对象前做相关操作"); } private void doAfter(){ System.out.println("调用目标对象后做相关操作"); } }
单元测试,具体代码如下:
package com.yoodb; public class MainTest { public static void main(String[] args) { Business business = new BusinessImplProxy(); business.doAction(); } }
运行之后结果如下:
调用目标对象前做相关操作 实现业务逻辑. 调用目标对象后做相关操作
2. 动态代理
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
1) Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组;这个抽象方法在代理类中动态实现。
2) Proxy:该类即为动态代理类,作用类似于上例中的ProxySubject,其中主要包含以下内容:
Protected Proxy(InvocationHandler h):构造函数,估计用于给内部的h赋值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)。
接口(或抽象类),具体代码如下:
package com.yoodb; public interface Business { public void doAction(); } 此处是真正意义上实现业务逻辑的类,具体代码如下: package com.yoodb; public class BusinessImpl implements Business { @Override public void doAction() { // TODO Auto-generated method stub System.out.println("实现业务逻辑."); } }
动态代理方式,具体代码如下:
package com.yoodb; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicBusinessProxy implements InvocationHandler{ private Object obj; public DynamicBusinessProxy() {} public DynamicBusinessProxy(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = null; doBefore(); result = method.invoke(obj, args); doAfter(); return result; } private void doBefore(){ System.out.println("调用目标对象前做相关操作"); } private void doAfter(){ System.out.println("调用目标对象后做相关操作"); } public static Object factory(Object obj) { Class<? extends Object> cls = obj.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new DynamicBusinessProxy(obj)); } }
单元测试,具体代码如下:
package com.yoodb; public class MainTest { public static void main(String[] args) { Business business = (Business) DynamicBusinessProxy.factory(new BusinessImpl()); business.doAction(); } }
运行之后结果如下:
调用目标对象前做相关操作 实现业务逻辑. 调用目标对象后做相关操作
关注下方微信公众号“Java精选”(w_z90110),回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。
本站文章除注明转载外,均由 素文宅 整理发布,欢迎任何形式的转载,但请务必注明出处。
转载请注明:文章转载自 素文宅博客 [https://blog.yoodb.com/]
本文标题:Java 设计模式之代理模式
分享:
支付宝
微信