前言
在Spring或者SpringBoot中,可以通过@Aspect注解和切点表达式等配置切面,实现对某一功能的织入。然而其内部到底是如何实现的呢?
实际上,Spring在启动时为切点方法所在类生成了代理类,通过操作代理类代替操作实际类,从而实现在真正调用方法之前或之后,插入一些我们自定义的逻辑。
如何生成代理类呢?
JDK动态代理
- JDK动态代理要求 被代理类必须有接口抽象。
- 通过实现 InvocationHandler 接口并实现 invoke(Object proxy, Method method, Object[] args) 方法进行自定义逻辑的织入:
- proxy :当前的代理类实例;
- method:被代理的方法;
- args:方法入参;
invoke方法的官方说明如下:即在
* Processes a method invocation on a proxy instance and returns
* the result. This method will be invoked on an invocation handler
* when a method is invoked on a proxy instance that it is
* associated with.
使用示例:
public class MyInvocationHandler implements InvocationHandler { private Object target; // 通过构造函数将配代理对象注入 public MyInvocationHandler(Object target) { this.target = target; } //回调 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我是代理,有人让我对你说:"); /**调用前,自定义业务*/ Object res = method.invoke(target, args); /**调用后,自定义业务*/ return res; } //获取代理类实例 public <T> T getProxyInstance(){ return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
调用与输出:
public static void main(String[] args) { HelloAOPImpl helloAOP = new HelloAOPImpl(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(helloAOP); HelloAOP proxy = myInvocationHandler.getProxyInstance(); proxy.sayHello(); } // 输出 我是代理,有人让我对你说: 你好,AOP
一个疑问:代理类如何取代被代理类的呢?