Java的dynamic proxy(动态代理)的使用学习(二)

这篇文章看一下如何从proxy里面取出实际对应的handler。可以在前一篇文章讲解的基础上,做一个InjectFieldProxyHandler

如上所示,可以看到我们在BasicProxyHandler的基础上扩展出来InjectFieldProxyHandler

在这个InjectFieldProxyHandler里面,我们添加了metadata这个field。然后要做的是,在使用proxy的实例的时候,同时也可以取得这里面的metadata

我们具体看一下源代码:

package io.alchemystudio.lang.proxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 展示如何从proxy里面提取handler。
// 这样就可以在handler里面封装metadata。
public class InjectFieldProxyHandler extends BasicProxyHandler {

    public InjectFieldProxyHandler(Object original) {
        super(original);
    }

    // 这个方法取不到。
    // 这个用来封装一个`metadata`的field。
    private Object metadata;

    public Object getMetadata() {
        return metadata;
    }

    public void setMetadata(Object metadata) {
        this.metadata = metadata;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(getOriginal(), args); // 直接pass给original的对应method。
    }

    public static void main(String[] args) {
        Foo foo = new FooImpl();

        Foo proxy = (Foo) Proxy.newProxyInstance(
                InjectFieldProxyHandler.class.getClassLoader(),
                new Class[]{Foo.class},
                new InjectFieldProxyHandler(foo));

        proxy.echo("Hello, world!");

        if (Proxy.isProxyClass(proxy.getClass())) {
            InjectFieldProxyHandler handler = (InjectFieldProxyHandler) Proxy.getInvocationHandler(proxy);
            handler.setMetadata(System.currentTimeMillis());
            System.out.println(handler.getMetadata());
        }

    }
}

可以看到和前一篇文章里面介绍的基础例子不同,这个class里面加了metadata这个field。并且我们在main()方法里面提取了它。

main()方法代码对应的逻辑图如下:

注意上面的代码当中,我们和前一篇文章当中基础的逻辑没什么不同,有区别的地方是最后我们通过Proxy.isProxyClass()方法来判断某个instance的class是不是proxy class,然后我们会使用Proxy.getInvocationHandler()方法来从instance当中得到proxy class对应的InvocationHandler

因此,我们的proxy class的instance就可以在原始class的基础上扩展了一个叫做metadata的field,并去实际的操作它。

这篇文章当中的代码在这里:

以上就是proxy的另一种使用方法。

My Github Page: https://github.com/liweinan

Powered by Jekyll and Theme by solid

If you have any question want to ask or find bugs regarding with my blog posts, please report it here:
https://github.com/liweinan/liweinan.github.io/issues