MethodInterceptor 的幾種用法


前言

最近在看springboot@EnableAsync的源碼,發現還是需要提前看一些東西,比如這次的MethodInterceptor接口的作用;如今springboot都到2.0以后了,我谷歌出來好多文章都是用的配置文件,本篇就用純代碼的形式來說明MethodInterceptor的用法;

正文

項目使用springboot的2.3.0.RELEASE版本構建,其中需要注意導入aopstarter

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        

注意:springboot項目中若未加入上面的包,案例一會報錯,案例二不會報錯,但是不會生效;

非注解

以下兩個案例都是針對非注解的

案例一

使用aspectj execution表達定義切點;這個就比較靈活了,主要就是看traceExecution怎么去寫了;

  1. 自己寫一個類實現MethodInterceptor接口的invoke()方法

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println(methodInvocation.getMethod().getName());
        return methodInvocation.proceed();
    }
}

  1. 使用 AspectJExpressionPointcut定義切點並注冊

@Configuration
public class InterceptorConfig {
   //注意該地址為項目具體包地址
   public static final String traceExecution = "execution(* com.example.methodinterceptor..*.*(..))";
   @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor2() {
        MyInterceptor interceptor = new MyInterceptor();
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression(traceExecution);

        // 配置增強類advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(interceptor);
        return advisor;
    }
}

案例二

這個案例主要是用JdkRegexpMethodPointcut來構造切點,這個就看Pattern參數怎么寫了;

  1. 自己寫一個類實現MethodInterceptor接口的invoke()方法

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println(methodInvocation.getMethod().getName());
        return methodInvocation.proceed();
    }
}

  1. 使用 JdkRegexpMethodPointcut定義切點

@Configuration
public class InterceptorConfig {
     @Bean
    public DefaultPointcutAdvisor defaultPointcutAdvisor() {
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPattern("com.example.methodinterceptor.*");
        // 配置增強類advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(new MyInterceptor());
        System.out.println(advisor.toString());
        return advisor;
    }
}

注解

  1. 自定義注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InterceptorAnnotation {
}

案例三

這個案例就是案例一,只是將AspectJExpressionPointcut的參數改變了Expression;
直接使用案例一代碼,然后將traceExecution修改就可以了


public static final String traceExecution = "annotation(com.example.methodinterceptor.annotation.InterceptorAnnotation)";

案例四

這個案例就是使用AnnotationMatchingPointcut來構造切點;

  1. 自己寫一個類實現MethodInterceptor接口的invoke()方法

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println(methodInvocation.getMethod().getName());
        return methodInvocation.proceed();
    }
}

  1. 使用AnnotationMatchingPointcut構造切點

注意: 這是使用的AnnotationMatchingPointcut構造方法;在參考文章1中使用的是:


AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(InterceptorAnnotation.class, true);

這個寫法並沒有對該注解進行攔截;在文章末尾的評論有提到這個問題;


@Configuration
public class InterceptorConfig {
     @Bean
    public Advisor pointcutAdvisor() {
        MyInterceptor interceptor = new MyInterceptor();

        AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(null,InterceptorAnnotation.class);
        // 配置增強類advisor
        DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
        advisor.setPointcut(pointcut);
        advisor.setAdvice(interceptor);
        System.out.println(advisor.toString());
        return advisor;
    }
}

總結

以上幾種案例感覺能滿足很多場景了,但是感覺每種場景都有很多案例支持,具體卻不知道選取哪一種,只有多看看源碼,去了解思想了;

最后

項目地址:
文章地址:

參考:

  1. 使用spring的MethodInterceptor實現aop功能的三種方式
  2. 透過現象看原理:詳解Spring中Bean的this調用導致AOP失效的原因
  3. Java AnnotationMatchingPointcut類代碼示例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM