最近在看springboot的@EnableAsync的源码,发现还是需要提前看一些东西,比如这次的MethodInterceptor接口的作用;如今springboot都到2.0以后了,我谷歌出来好多文章都是用的配置文件,本篇就用纯代码的形式来说明MethodInterceptor的用法
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
项目使用springboot的2.3.0.RELEASE版本构建,其中需要注意导入aop的starter;
注意: 在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();
}
}
2,使用 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();
}
}
2,使用 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;
}
}
注解
自定义注解
@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();
}
}
2,使用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;
}
}
总结
以上几种案例感觉能满足很多场景了,但是感觉每种场景都有很多案例支持,具体却不知道选取哪一种,只有多看看源码,去了解思想了;
最后
网友评论