JAVA动态代理机制简单应用

来源:互联网 发布:360拒绝安装软件 编辑:程序博客网 时间:2024/05/16 05:24

一 概念

在上一篇博文中介绍了代理模式,Java动态代理机制使得Java开发人员不用手工编写代理类,只要简单的指定一组接口(抽象角色)和委托类(真实角色)对象,便能动态的获得代理类。代理类会负责将所有的方法调用分派到真实角色上反射执行,在分配执行的过程中,开发人员还可以按需调整委托类对象及其功能。

二 代码

场景:度量一段计算10000000次浮点乘法的代码的运行时间(与上一篇博文简单代理模式场景相同)。

2.1 抽象角色ComputeInterface——通过接口或抽象类声明真实角色实现的业务方法(再此为compute())

public interface ComputeInterface {void compute();}

2.2 真实角色RealCompute——实现抽象角色,定义真实角色所要实现的业务逻辑(实现compute()方法)。

public class RealCompute implements ComputeInterface {@Overridepublic void compute() {double result=1.0;System.out.println("正在进行10000000次浮点乘法...");for(int i=0;i<10000000;i++){ result*=1.123345;}}}

2.3 调用处理器TimeHandler

public class TimeHandler implements InvocationHandler {private Object proxiedObject;public TimeHandler(Object proxiedObject) {this.proxiedObject=proxiedObject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("开始运行...");long startTime=System.currentTimeMillis();Object object= method.invoke(proxiedObject, args);long endTime=System.currentTimeMillis();System.out.println("运行结束,运行时间为:"+ (endTime-startTime));return object;}}

2.4 客户类TestCompute——用于测试代码

public class TestCompute {public static void main(String[] args) {ComputeInterface timeProxy=(ComputeInterface)Proxy.newProxyInstance(ComputeInterface.class.getClassLoader(),new Class[]{ComputeInterface.class},new TimeHandler(new RealCompute()));timeProxy.compute();}}

运行结果如下:

开始运行...
正在进行10000000次浮点乘法...
运行结束,运行时间为:31

2.5 分析

与简单代理模式相比,动态代理采用了实现InvocationHandler接口的调用处理器,而并没有显示的写出代理类(通过Proxy.newProxyInstance()动态生成代理类)。

三 进一步

场景:现在想在开始程序之前先记录是谁运行了程序,运行程序完毕提示谁结束了运行程序。

3.1 添加调用处理器NameHandler

public class NameHandler implements InvocationHandler{private Object proxiedObject;private String name;public NameHandler(Object proxiedObject,String name) {this.proxiedObject=proxiedObject;this.name=name;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(name+"运行了程序!");Object object= method.invoke(proxiedObject, args);System.out.println(name+"运行程序完毕!");return object;}}

3.2 修改测试类TestCompute

public class TestCompute {public static void main(String[] args) {ComputeInterface timeProxy=(ComputeInterface)Proxy.newProxyInstance(ComputeInterface.class.getClassLoader(),new Class[]{ComputeInterface.class},new TimeHandler(new RealCompute()));ComputeInterface nameTimeProxy=(ComputeInterface)Proxy.newProxyInstance(ComputeInterface.class.getClassLoader(),new Class[]{ComputeInterface.class},new NameHandler(timeProxy,"小明"));nameTimeProxy.compute();}}

运行结果如下:

小明运行了程序!
开始运行...
正在进行10000000次浮点乘法...
运行结束,运行时间为:40
小明运行程序完毕!

3.3 分析

如果需要新的代理角色,重新写一个继承与InvocationHandler的调用处理器,再该类中附加代码即可。