SpringAop篇 (1) AOP 基础之动态代理的实现
介绍
Spring AOP 主要通过动态代理来实现的,所以我们需要在介绍 AOP 用法之前,先来介绍下动态代理的用法以及本质。
对于动态代理的理解可以借鉴普通代理模式。我们普通的Java代理需要为一个对象建立专门的代理对象,通过调用代理对象,来实现原对象的各种功能。
而动态代理区别于普通代理方式,动态代理是在运行时产生的代理类。
动态代理实现方式
-
通过实现 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对象上