更简单的动态代理

更简单的动态代理

很多情况下我们需要对某个对象进行动态代理,然而JDK的代理非常繁琐
大部分情况会写成这样:

Proxy.newProxyInstance(
    toProxy.getClass().getClassLoader()
    , toProxy.getClass().getInterfaces()
    ,handler);


有一种封装方式大家都知道,省略classloader参数,并把interfaces参数换成要代理的对象。比如这样:

<T> T proxy(InvocationHandler handler, T toProxy) {
    return (T) 
    Proxy.
        newProxyInstance(
            toProxy.getClass().getClassLoader(), 
            toProxy.getClass().getInterfaces(),
            handler);
}

但是本文不研究这种封装。

继续简化

如果你仅仅需要对某些方法进行封装,也许你会在InvocationHandler中写大量的

if(method.getName().equals(...)){...}

而且代码很不好看。如果能够写成这样会不会更好呢?

new ProxyHandler(toProxy){
    ReturnType0 methodName0(T0 arg0, T1 arg1, ...){...}
    ReturnType1 methodName1(T0 arg0, T1 arg1, ...){...}
}

举个例子,对于List的get方法,现在需要在调用get前输出

before get invoked with arg0: + index

在get后输出

after get invoked with res: + 结果

你可以这么做:

List<String> listProxy 
= proxy(new ProxyHandler<List<String>>(list) {
    @SuppressWarnings("unused")
    String get(int index) {
        System.out.println("before get invoked with arg0:" + index);
        String res = toProxy.get(index);
        System.out.println("after get invoked with res:" + res);
        return res;
    }
});

由于匿名类内部并没有直接调用get函数,所以会出现unused警告,使用注解suppress它即可。

代码非常简洁,从定义上完全与List中的方法相同。

如何实现?

非常简单。在调用时,获取proxyhandler中对应名称和参数的方法,如果找不到,则直接调用原对象方法。如果找到,则调用proxyhandler对象的方法。

注意,不能直接method.invoke(proxyhandler,args….),因为虽然定义一致,但本身它们是两种方法。

有没有直接可以用的代码呢?

Style工具集(在版本 1.0.2 或以上 )提供这种实现方式。
https://github.com/wkgcass/Style
调用Style.proxy(proxyHandler)即可。

Style要求 JDK1.8 或以上
您可以参考源代码或者大致思路自行实现它
如果觉得Style好用请点个星哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值