Java设计模式之动态代理(jdk动态代理)

上篇文章降到了静态代理, 但是代理类只能通过实现固定接口来完成;

所以我们这篇讲JDK动态代理, 在讲之前我们先打开jdk 的帮助文档来查看一个关键的类, Proxy

-----------------------------------------------------------

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

例:创建某一接口 Foo 的代理:

     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
                                          new Class[] { Foo.class },
                                          handler);
 

动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。 代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。 

-----------------------------------------------------------------------

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h) throws IllegalArgumentException
参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
返回:
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口 

代码如下:

public class BigProxy implements InvocationHandler {

    private  TxManager manager ;
    private Object target;

    public BigProxy(TxManager manager, Object target) {
        this.manager = manager;
        this.target = target;
    }

    public  Object createProxy (Object target ){
        return java.lang.reflect.Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        try {
            if (method.getName().equals("save")){
                manager.begin();
                result = method.invoke(target,args);
                manager.commit();
                return result;
            }else{
                result = method.invoke(target,args);
                return result;
            }
        } catch (Exception e) {
            manager.rollback(e);
        } finally {
            manager.release();
        }
        return null;
    }
}

测试类:

public static void main(String[] args) {
    OrderService orderService = new OrderSerivceImpl();
    BigProxy bigProxy = new BigProxy( new TxManager(),orderService);
    System.out.println(bigProxy + "|" + bigProxy.getClass());
    Order order = new Order();
    order.setDate(new Date().toString());
    order.setOperateName("zz");
    order.setOrderId("111");
    order.setProductName("可乐");
    Object proxy = bigProxy.createProxy(orderService);
    System.out.println(proxy.getClass());
    System.out.println("------------------");
    if (proxy instanceof OrderService){
        OrderService orderServiceProxy = (OrderService)proxy;
        orderServiceProxy.query("aaa");
        orderServiceProxy.save(order);
    }

}


输出结果为:

Java设计模式之动态代理(jdk动态代理)_第1张图片


jdk动态代理的缺点就是, 传入需要代理的对象必须是有接口的,否则就会报错!!! 所以下面介绍更优秀的代理模式(Cglib代理)

你可能感兴趣的:(设计模式,Java设计模式(企业实战))