Spring Boot进阶:原理、实战与面试题分析
上QQ阅读APP看书,第一时间看更新

3.2.1 JDK动态代理

在JDK自带的动态代理中存在一个InvocationHandler接口,我们首先要做的就是提供一个该接口的实现类,如代码清单3-7所示。

代码清单3-7 InvocationHandler接口实现类代码

public class AccountHandler implements InvocationHandler{
    private Object obj;

    public AccountHandler(Object obj) {
        super();
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] arg)
            throws Throwable {
        Object result = null;
        doBefore();
        result = method.invoke(obj, arg);
        doAfter();
        return result;
    }

    public void doBefore() {
        System.out.println("开户前");
    }

    public void doAfter() {
        System.out.println("开户后");
    }
}

InvocationHandler接口中包含一个invoke()方法,我们必须实现这一方法。在该方法中,通常需要调用method.invoke()方法执行原有对象的代码逻辑,然后可以在该方法前后添加相应的代理实现。在上述代码中,我们只是简单打印了日志。

然后,编写测试类来验证上述AccountHandler类的执行效果,如代码清单3-8所示。

代码清单3-8 AccountHandler测试类代码

public class AccountTest {
    public static void main(String[] args) {
        Account account = new RealAccount("tianyalan");
        InvocationHandler handler = new AccountHandler(account);

        Account proxy = (Account)Proxy.newProxyInstance(
            account.getClass().getClassLoader(),
            account.getClass().getInterfaces(),
            handler);
        proxy.open();
    }
}

这里的Proxy.newProxyInstance()方法的作用就是生成代理类。当该方法被调用时,RealAccount类的实例被传入。然后当代理类的open()方法被调用时,AccountHandler中invoke()方法就会被触发,从而实现代理机制。这里的类层次结构如图3-4所示。

066-1

图3-4 JDK动态代理类层次结构示意图

仔细分析上述代码结构,可以发现其遵循“设计并实现业务接口→实现Handler→创建代理类”这一流程,然后在Handler中构建具体的代理逻辑。上述流程也是代表了基本的代理机制实现流程。联想一下,很多基于AOP机制的拦截器底层实际上就是类似的原理。