java设计模式之 代理模式

代理模式简介
代理模式在JDK和java开源项目中都有非常广泛的应用 。我们实际开发过程中也经常会用到代理模式 。
代理模式的定义:给某一个对象提供一个代理 , 并由代理对象控制对原对象的引用
两个对象参与同一个请求 , 接收到的请求由代理对象委托给真实对象处理 , 代理对象控制请求的访问 , 它在客户端应用与真实目标之间起到一个中介桥梁的作用 。
代理模式包含如下角色:
实现动态代理的关键技术是**反射**
静态代理
代理模式可以分为静态代理和动态代理两种 , 静态代理比较简单 , 就是硬编码方式 , 不够灵活 , 而且代码繁多 。所以一般不会使用静态代理 , 这里就不多说了 。
动态代理
为了解决静态代理存在的问题 , 就有了动态地创建Proxy的想法:在运行状态中 , 需要代理的地方 , 根据 和 , 动态地创建一个Proxy , 用完之后 , 就会销毁 , 这样就可以避免了Proxy 角色的class在系统中冗杂的问题了 。

java设计模式之 代理模式

文章插图
接下来我们以最基本的添加日志功能演示一下代理的实现
JDK实现动态代理 jdk的动态代理步骤
创建一个实现`InvocationHandler`接口的类 , 它必须实现invoke()方法
【java设计模式之 代理模式】创建被代理的类及接口
调用Proxy的静态方法 , 创建一个代理类
通过代理调用方法
/*** Created by liubenlong on 2017/2/3.* 动态代理使用到的接口*/public interface HelloWorld {void sayHello(String name);}
实现类
public class HelloWorldImpl implements HelloWorld {@Overridepublic void sayHello(String name) {System.out.println("我是RealSubject 。Hello " + name);}}
日志代理类
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/*** Created by liubenlong on 2017/2/3.* 日志代理类*/public class CustomInvocationHandler implements InvocationHandler {private Object target;public CustomInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("beforelog...");Object invoke = method.invoke(target, args);System.out.println("endlog... 。该方法总共执行时间是10毫秒 。");return invoke;}}
测试方法:
public static void main(String[] args){System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");HelloWorldImpl helloWorld = new HelloWorldImpl();CustomInvocationHandler handler = new CustomInvocationHandler(helloWorld);HelloWorld proxyInstance = (HelloWorld) Proxy.newProxyInstance(HelloWorldImpl.class.getClassLoader(),new Class[]{HelloWorld.class},handler);proxyInstance.sayHello("haha");}
输出结果:
beforelog...我是RealSubject 。Hello hahaendlog... 。该方法总共执行时间是10毫秒 。
到这里 , 我们就可以使用jdk的动态代理来编写代码了 。但是为什么需要这几步 , JDK内部是怎么实现的呢?这个问题可以从Proxy和的源码中找打答案 。
JDK动态代理原理与源码
这里使用的jdk版本是:1.8.0_111
()方法的源码:
@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class