Java代理模式及动态代理

前言

最近查看retrofit的源码,发现其用到了java的动态代理机制,于是代理模式以及动态代理进行了一番了解。学习动态代理机制前重要的是先了解一下什么是代理模式

先贴出一些教科书知识

什么是代理模式?

为另一个对象提供一个可以操控的入口
例如你创建了一个对象,但是你不希望客户直接引用你的这个对象,这是你可以给客户提供一个代理,让客户操控这个代理,来访问你创建的对象。
此时真是的角色和代理都要实现同一个接口。

这就是代理模式。稍后上代码。

什么是动态代理?

我就不写了,推荐一篇优秀教程:Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

贴出一段代理模式代码(静态代理)

代理和被代理者共同实现的接口

public interface Subject {

    void hello(String word);
}

代理

public class ProxySubject implements Subject {

    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void hello(String word) {
        System.out.println("在调用真正的角色方法之前,做一些事情");
        subject.hello(word);
        System.out.println("在调用真正的角色方法之后,做一些事情");
    }

}

被代理者

public class RealSubject implements Subject {

    @Override
    public void hello(String word) {

        System.out.println(word);
    }

}

这样就可以通过代理来调用代理者的方法了。

关于动态代理

对比与静态代理,静态代理的“代理”和“被代理”存在一些关联:共同实现了一个接口。而动态代理是,java官方为我们提供了一个“代理”,这个代理可以代理任何对象。这个对象可以输入任意类。

java提供了代理类:Proxy
查看jdk可以查看,怎样创建一个代理:

public static Object newProxyInstance(ClassLoader loader,
                      Class<?>[] interfaces,
                      InvocationHandler h)
                               throws IllegalArgumentException

其中有三个参数:

    loader - the class loader to define the proxy class //类加载器
    interfaces - the list of interfaces for the proxy class to implement //被代理者实现的接口字节码对象,强调一下,此处必须是接口的字节码对象
    h - the invocation handler to dispatch method invocations to  //执行代理具体操作的手柄

通过代码演示一下怎样使用动态代理,来调用被代理者的方法。

public class Test {

    public static void main(String[] args) {

        RealSubject realSubject = new RealSubject();

        Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
                new Class[] { Subject.class }, new InvocationHandler() {
                    private Object object = realSubject;

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 方法调用之前做一些事情

                        method.invoke(object, args);
                        return null;
                    }
                    // 方法调用之后做一些事情
                });

        subject.hello("hello,world");
    }

}

其中InvocationHandler 的invoke方法中的参数method就是代理调用的方法,args就是方法的参数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值