• 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类代码示例
  • 相关阅读:
    正则表达式解决身份证号码和手机号
    redis:集群配置
    linux:NFS
    xshell提示必须安装最新的更新
    linux:ssh远程调用tomcat脚本时候出错
    linux:scp从入门到刚入门
    linux:SSH最简单教程
    nginx;keepalived配置出现主主的解决方法(脑裂问题)
    (4)事件处理——(4)网页上的多个脚本(Multiple scripts on one page)
    [php]应用控制器(一)
  • 原文地址:https://www.cnblogs.com/guoyuchuan/p/13068581.html
Copyright © 2020-2023  润新知