SpringAop篇 (1) AOP 基础之动态代理的实现

介绍

Spring AOP 主要通过动态代理来实现的,所以我们需要在介绍 AOP 用法之前,先来介绍下动态代理的用法以及本质。

对于动态代理的理解可以借鉴普通代理模式。我们普通的Java代理需要为一个对象建立专门的代理对象,通过调用代理对象,来实现原对象的各种功能。

SpringAop篇 (1) AOP 基础之动态代理的实现

而动态代理区别于普通代理方式,动态代理是在运行时产生的代理类。

动态代理实现方式

  • 通过实现 InvocationHandler 接口创建自己的调用处理器;

  • 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

  • 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

  • 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

  • 接口:

public interface Action {
    public int action();
}
  • 实现类:
public class LogAction implements Action{
    public int action(){
        System.out.println("action");
        return 20;
    }
}
  • 代理类 :
public class ActionInvocationHandlerImpl implements InvocationHandler {
    private Object action;

    public ActionInvocationHandlerImpl(Object action)
    {
        this.action = action;
    }


    public Action getAction(){
        return (Action) Proxy.newProxyInstance(action.getClass().getClassLoader(),
                action.getClass().getInterfaces(),
                this);

    }
    /**
     * <pre>
     *     动态代理具体的实现类
     * </pre>
     *
     * @param proxy 具体的代理对象
     * @param method 当前调用的方法
     * @param args 调用参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("Before action");
        Object value = method.invoke(action, args);
        System.out.println("End action");

        return value;
    }
}
  • 例子
public class Main {
    public static void main(String[] args) {
        Action action = new ActionInvocationHandlerImpl(new LogAction()).getAction();
        action.action();
    }
}

说明:

每一个动态代理类都必须要实现 InvocationHandler 这个接口(代码中的中介),并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke(对方法的增强就写在这里面) 方法来进行调用。

Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法:

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

 
//loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
//interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
//h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上