(造轮子)手写Spring框架-几种常用的Advice:BeforeAdvice/AfterAdvice/AfterReturningAdvice...

190 阅读2分钟

几种常用的Advice:BeforeAdvice/AfterAdvice...

代码地址:github.com/WangChao-ly…

建议订阅博主专栏,从下到上系统手写spring源码,体会其中过程!

Spring将AOP联盟中的Advice细化出各种类型的Advice,常用的有BeforeAdvice/AfterAdvice/AfterReturningAdvice/ThrowsAdvice,我们可以通过扩展MethodInterceptor来实现。

只简单实现BeforeAdvice,有兴趣的同学可以帮忙实现另外几种Advice。定义MethodBeforeAdviceInterceptor拦截器,在执行被代理方法之前,先执行BeforeAdvice的方法。

  • BeforeAdvice:该接口继承了Advice接口,标识该接口为一个Advice接口。
  • MethodBeforeAdvice:该接口继承了BeforeAdvice,表明该接口为一个BeforeAdvice,实现了该接口的类可以重写before方法,自定义在节点匹配的方法执行前做的操作。同时该接口中的before方法会在MethodBeforeAdviceInterceptor被调用,而该Interceptor会在代理代理对象生成后匹配到方法时执行。
  • MethodBeforeAdviceInterceptor:该类通过注入MethodBeforeAdvice,然后实现在方法调用之前先调用before方法,然后在调用匹配的方法。
/**
 * 定义MethodBeforeAdviceInterceptor拦截器
 * 在执行被代理方法之前,先执行BeforeAdvice的方法。
 * @author WangChao
 * @date 2023-07-12 21:27
 */
public class MethodBeforeAdviceInterceptor implements MethodInterceptor {

    private MethodBeforeAdvice methodBeforeAdvice;

    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice methodBeforeAdvice){
        this.methodBeforeAdvice = methodBeforeAdvice;
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        //在执行被代理方法之前,先执行before advice操作
        this.methodBeforeAdvice.before(invocation.getMethod(),invocation.getArguments(),invocation.getThis());
        // 执行方法
        return invocation.proceed();
    }
}
  • 测试:实现MethodBeforeAdvice接口,重写before方法,注入到MethodBeforeAdviceInterceptor中。
public class WorldServiceBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("BeforeAdvice: do something before the earth explodes");
    }
}
@Test
public void testBeforeAdvice() throws Exception{
    //设置BeforeAdvice
    MethodBeforeAdvice beforeAdvice = new WorldServiceBeforeAdvice();
    MethodBeforeAdviceInterceptor methodBeforeAdviceInterceptor = new MethodBeforeAdviceInterceptor(beforeAdvice);
    // 定义拦截类,在代理方法执行时候处理一些操作
    support.setMethodInterceptor(methodBeforeAdviceInterceptor);

    WorldService proxy = (WorldService) new ProxyFactory(support).getProxy();
    proxy.explode();
}

总结:本节实现的前置通知类似之前实现的那种MethodInterceptor,只是在aop中表明了容器提供前置通知的功能,用户只需要自定义前置功能即可。