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);
    }

}


输出结果为:



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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值