java中动态代理的使用
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
下面我们通过实例来展示动态代理在java程序中的简单应用。
这是我们示例的整体架构,由接口、实现类、代理类和测试类组成。
我们先定义一个接口类,也是我们需要代理的类。
package com.wenbing.proxyreflect; public interface OrderService { int sum(int total); Long getPrice(int size); }
创建我们被代理类的实现类。
package com.wenbing.proxyreflect; public class OrderServiceImpl implements OrderService { @Override public int sum(int total) { return total*10; } @Override public Long getPrice(int size) { return size*30L; } }
创建代理类,实现InvocationHandler接口。
package com.wenbing.proxyreflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; //代理类 public class Proxy implements InvocationHandler { // 需要代理的目标 private Object target; // 使用构造方法传入需要代理的目标 public Proxy(Object target) { this.target = target; } /** * 横切面逻辑 * * @param proxy 产生代理的实例 * @param method 需要代理的方法 * @param args 方法参数 * @return 代理方法的返回值 * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 方法执行前的业务 System.out.println("方法执行前的业务"); // 使用反射执行方法 Object result = method.invoke(target, args); System.out.println(result); // 方法执行后的业务 System.out.println("方法执行后的业务"); return result; } }
创建测试类Test,通过动态代理的方法去完成方法的调用获取结果。
package com.wenbing.proxyreflect; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) throws Exception { OrderServiceImpl orderService = new OrderServiceImpl(); // 获取代理 OrderService os = (OrderService) Proxy.newProxyInstance(Test.class.getClassLoader(), orderService.getClass().getInterfaces(), new com.wenbing.proxyreflect.Proxy(orderService)); Long price = os.getPrice(10); System.out.println("价格为:"+price); System.out.println("========================="); int sum = os.sum(5); System.out.println(sum); } }
这个小例子非常简单,很适合入门去理解动态代理的小白,自己跟着代码敲一遍将受益匪浅。
纸上得来终觉浅,绝知此事要躬行,赶紧跟着敲一敲吧。