提出一个问题
在实际的编程过程中,你可能会遇到这样的问题。你拥有以下的业务逻辑:A, B 和 C,在最初的设计过程中,你的程序在执行B之前,要先执行A,在执行B之后,要紧接着最后执行C。可是随着业务的调整,你不想在B之前执行A了,甚至想重新增加一个D来替换A。有没有不修改代码的前提下动态的进行这样的逻辑调整?动态代理就可以用来解决这个问题。
什么是动态代理
Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface
的实例。
使用动态代理,一般是为了给需要实现的方法添加预处理或者添加后续操作,但是不干预实现类的正常业务,把一些基本业务和主要的业务逻辑分离。
23种设计模式中的面向切面编程 (AOP) 就是以动态代理机制基础的。
基于JDK的动态代理如何实现
首先定义一个接口
package ProxyStudy; public interface Hello { public void sayHello(); }
然后编写这个接口的实现类
package ProxyStudy; public class Helloer implements Hello { @Override public void sayHello() { System.out.println("Helloer says: Hello!"); } }
在静态实现的过程中,你一定会这样做
Helloer helloer = new Helloer(); helloer.sayHello();
但是在动态代理中,首先要定义一个 ProxyHandler 类,并实现 InvocationHandler 接口。
package ProxyStudy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ProxyHandler implements InvocationHandler { private Object subject; public ProxyHandler(Object subject) { this.subject = subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("I am ready to do something..."); Object invoker = method.invoke(subject, args); System.out.println("I am done~"); return invoker; } }
这样,你就可以通过Proxy来动态生成一个代理对象,然后通过调用这个代理对象来实现真正对象的方法。实际上调用的是代理对象的invoke方法。
package ProxyStudy; import java.lang.reflect.Proxy; public class Main { public static void main(String[] args) { // 创建目标对象 Hello hello = new Helloer(); // 创建调用处理器对象 ProxyHandler proxyHandler = new ProxyHandler(hello); // 动态生成代理对象 Hello helloProxy = (Hello) Proxy.newProxyInstance( Helloer.class.getClassLoader(), Helloer.class.getInterfaces(), proxyHandler); // 通过代理对象调用方法 helloProxy.sayHello(); } }
实际的输出:

动态代理的意义
如上面的代码,你可以把“I am ready to do something”替换成一些执行真正方法前要进行的东西,把“I am done” 替换成一些执行真正方法后要进行的“收尾”工作的东西。动态代理使得在不修改业务类的情况下,能很方便的增加一些其他操作。
文章评论