springboot切面AOP拦截父类或接口中标记注解的方法
一、注解的继承性回顾
- 被@Inherited元注解标注的注解标注在类上的时候,子类可以继承父类上的注解。
- 注解未被@Inherited元注解标注的,该注解标注在类上时,子类不会继承父类上标注的注解。
- 注解标注在接口上,其子类及子接口都不会继承该注解
- 注解标注在类或接口方法上,其子类重写该方法不会继承父类或接口中方法上标记的注解
根据注解继承的特性,我们再做AOP切面拦截的时候会遇到拦截不到的问题,今天我们就讲解下对这些特殊情况如何解决,对源码不做过渡深入的讲解。
二、注解标注在父类、接口、父类方法、接口方法上如何通过子类拦截,首先了解下几个核心类
AnnotationMatchingPointcut切点类是用来判定是否需要拦截类、父类、实现接口中方法,其中一共四个构造函数如下:
/*** Create a new AnnotationMatchingPointcut for the given annotation type.* @param classAnnotationType the annotation type to look for at the class level*/
public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType) {this(classAnnotationType, false);}/*** Create a new AnnotationMatchingPointcut for the given annotation type.* @param classAnnotationType the annotation type to look for at the class level* @param checkInherited whether to also check the superclasses and interfaces* as well as meta-annotations for the annotation type* @see AnnotationClassFilter#AnnotationClassFilter(Class, boolean)*/public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType, boolean checkInherited) {this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited);this.methodMatcher = MethodMatcher.TRUE;}/*** Create a new AnnotationMatchingPointcut for the given annotation types.* @param classAnnotationType the annotation type to look for at the class level* (can be {@code null})* @param methodAnnotationType the annotation type to look for at the method level* (can be {@code null})*/public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType,@Nullable Class<? extends Annotation> methodAnnotationType) {this(classAnnotationType, methodAnnotationType, false);}/*** Create a new AnnotationMatchingPointcut for the given annotation types.* @param classAnnotationType the annotation type to look for at the class level* (can be {@code null})* @param methodAnnotationType the annotation type to look for at the method level* (can be {@code null})* @param checkInherited whether to also check the superclasses and interfaces* as well as meta-annotations for the annotation type* @since 5.0* @see AnnotationClassFilter#AnnotationClassFilter(Class, boolean)* @see AnnotationMethodMatcher#AnnotationMethodMatcher(Class, boolean)*/public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType,@Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) {Assert.isTrue((classAnnotationType != null || methodAnnotationType != null),"Either Class annotation type or Method annotation type needs to be specified (or both)");if (classAnnotationType != null) {this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited);}else {this.classFilter = new AnnotationCandidateClassFilter(methodAnnotationType);}if (methodAnnotationType != null) {this.methodMatcher = new AnnotationMethodMatcher(methodAnnotationType, checkInherited);}else {this.methodMatcher = MethodMatcher.TRUE;}}
以上四个构造函数,支持仅标记在类上注解、仅标记方法上的注解、即指定标记类上且标记在方法上的注解(是否拦截父类及接口上标记的方法)三种构造方式。
通过上述四个构造函数可以构造如下几种切点类型:
- 注解标注在当前类,只拦截当前类的方法
- 注解标注在当前类的父类上,拦截父类及子类中的方法
- 注解标注在当前类实现的接口上 ,拦截接口方法的实现方法
- 注解标注在当前类的方法上,拦截当前类的方法
- 注解标注在当前类父类或接口的方法上,拦截父类的方法或者当前类实现方法。
通过上述切点可以构造出我们需要的大多数场景,如果需要更灵活的实现还需要结合ComposablePointcut类,此类可以实现类级别标注的交集、并集,方法级别的交集、并集,切点级别的交集并集。
三、切点实现案例
@Bean@Role(BeanDefinition.ROLE_INFRASTRUCTURE)public Advisor mybatisLogAdvisor(MybatisProperties properties) {//限定类级别的切点Pointcut cpc = new AnnotationMatchingPointcut(Mapper.class, properties.isCheckClassInherited());//限定方法级别的切点Pointcut mpc = new AnnotationMatchingPointcut(null, Mapper.class, properties.isCheckMethodInherited());//组合切面(并集),一、ClassFilter只要有一个符合条件就返回true,二、Pointcut pointcut = new ComposablePointcut(cpc).union(mpc);//mybatis日志拦截切面MethodInterceptor interceptor = new MybatisMethodInterceptor();//切面增强类AnnotationPointcutAdvisor advisor = new AnnotationPointcutAdvisor(interceptor, pointcut);//切面优先级顺序advisor.setOrder(AopOrderInfo.MYBATIS);return advisor;}
此拦截器可以实现对标注了Mapper方法进行日志拦截,具体实现可以参考GitHub源码
四、上述向上查询父类、父接口及其方法的核心是AnnotatedElementUtils工具类,示例参考如下:
//返回当前类或父类或接口方法上标注的注解对象
targetDataSource = AnnotatedElementUtils.findMergedAnnotation(method, TargetDataSource.class);
//返回当前类或父类或接口上标注的注解对象
targetDataSource = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), TargetDataSource.class);
GitHub地址:https://github.com/mingyang66/spring-parent
springboot切面AOP拦截父类或接口中标记注解的方法相关推荐
- SpringBoot切面AOP打印请求和响应日志
1.说明 Spring Boot微服务对外开放的Restful接口, 为了方便定位问题, 一般需要记录请求日志和响应日志, 而在每个接口中开发日志代码是非常繁琐的, 本文介绍使用Spring的切面AO ...
- Java接口、implements关键字、接口中抽象方法,默认方法,静态方法,私有方法,常量、final关键字
接口: 接口是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量.构造方法和成员方法,那么 接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JD ...
- java private 接口_java接口中 定义 private 私有方法
在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private私有方法.只允许我们定义public访问权限的方法.抽象方法或静态方法.但是从Java 9 开 ...
- Java私有方法解释_java接口中 定义 private 私有方法
在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private私有方法.只允许我们定义public访问权限的方法.抽象方法或静态方法.但是从Java 9 开 ...
- Java 8——接口中个的默认方法和静态方法
在Java SE 8之前,interface只是事物的抽象,用来定义统一的抽象事物和描述事物的抽象行为和属性. 但是在Java SE 8中,增加了可以在interface中增加默认实现的行为和事物的静 ...
- java 打成war_JAVA语言之Springboot打成war包并在tomcat中运行的部署方法
本文主要向大家介绍了JAVA语言的Springboot打成war包并在tomcat中运行的部署方法,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 把spring-boot项目按照平常 ...
- 设计一个接口, 并设计一个实现类实现该接口,演示它们的使用。具体,创建一个名称为Person的接口,在接口中定义两个方法sayHello()和sayBye()。
设计一个接口, 并设计一个实现类实现该接口,演示它们的使用. 具体,创建一个名称为Person的接口,在接口中定义两个方法sayHello()和sayBye().然后,创建两个实现了Person接口的 ...
- spring面向切面aop拦截器
spring中有很多概念和名词,其中有一些名字不同,但是从功能上来看总感觉是那么的相似,比如过滤器.拦截器.aop等. 过滤器filter.spring mvc拦截器Interceptor .面向切面 ...
- 验证码及登录切面Aop拦截代码
首先定义验证码和登录监测的两个注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; im ...
最新文章
- SQLServer表内自关联级联删除
- 服务人员在Hybris ASM手动分配coupon给某个客户
- [JavaWeb]Web概念概述
- c++和c语言的区别_C与C++傻傻分不清楚,有啥区别,咋用,杂学?
- js怎么动态加载js文件(JavaScript性能优化篇)
- linux系统装psp,Linux上的PSP模拟器PPSSPP 1.7 发布了
- 在Vue中使用Echarts可视化库的完整步骤记录
- 利用函数指针实现累加
- Java生成简单的验证码图片
- 用html做龙卷风特效,利用HTML5实现Canvas龙卷风特效
- React基础之事件机制
- Unity程序员如何提升自己的能力
- Maven下载sources时报错java.lang.RuntimeException: Cannot reconnect
- 逆天神器!“国外“最新版本,直接一键破解所有WiFi密码,傻眼了!
- 易点易动【设备管理】产品全新上线
- 自注意力中的不同的掩码介绍以及他们是如何工作的?
- 第4章第15节:图表:使用饼图制作投资公司四季收益图表 [PowerPoint精美幻灯片实战教程]
- 《IT老外在中国》第22期:“中国餐桌”上的法式创新
- Android 如何OTG 鼠标,otg键盘和鼠标映射软件v5.2.0 Android版
- python趣味程序_python游戏趣味编程:疯狂的小圆圈