Spring Aspect切面类的使用
最近的做的一个功能是在用户插入数据的时候插入拿到所有每个字段,遍历这些字段,插入痕迹表中。还有更新了哪个字段,就要从数据库中拿出数据将以前的字段数据和现在的字段数据做对比,并插入痕迹表。
要处理这个很简单,直接复制一个新的别表,作为历史表,插入数据的时候在插入这个表,这不是很简单吗?
不不不,我要处理20多个模块,这个不太现实,主要有3个原因:
1、代码冗余,重复量多。
2、数据库结构不好维护,修改字段复杂度高。
3、必须重新为每一个痕迹表定义service层和dao,非常的麻烦。
于是我选择使用公共的痕迹表去处理,涉及到的知识有AOP,Aspect切面类,枚举,以及上一篇文章的多线程并发。
第一步:在Spring的配置文件中添加下行
<aop:aspectj-autoproxy />
第二步:建立切面类
@Aspect // 定义切面类
@Component //声明组件
public class CheckDataAspect {
private static Logger log = LoggerFactory.getLogger(CheckDataAspect.class);/**
* 监控财务核算电子数据报送联络人信息表更新
* @param point
*/
@Before("execution(* com.minstone.modules.ediis.checkData.service.CheckContactInfoService.updateByPrimaryKeySelectiveWithLog(..))")
public void checkContactInfoUpdateBefore(JoinPoint point){
updateLog(point);
}
/**
* 财务核算电子数据报送联络人信息表里面删除一条
*/
@Before("execution(* com.minstone.modules.ediis.checkData.service.CheckContactInfoService.deleteByCode(..))")
public void checkContactInfoDeleteBefore(JoinPoint point){
String bus_type = "EDIIS_CHECK_CONTACT_INFO";
deleteLog(point, bus_type);
}..........
..........
..........
}
第三步:建立枚举类(略),枚举类用来映射实体类,service,表名等等信息,然后利用反射获取各种业务类和方法,各个业务不同所以说这里展示也没啥意义,具体枚举类的操作可参考百度
如上,可完成在用户增删改的之前或之后添加操作的痕迹。
下面是切面类的附属使用方法
2 注解说明
2.1 @Aspect
作用是把当前类标识为一个切面供容器读取
2.2 @Before
标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
2.3 @AfterReturning
后置增强,相当于AfterReturningAdvice,方法正常退出时执行
2.4 @AfterThrowing
异常抛出增强,相当于ThrowsAdvice
2.5 @After
final增强,不管是抛出异常或者正常退出都会执行
2.6 @Around
环绕增强,相当于MethodInterceptor
2.7 @DeclareParents
引介增强,相当于IntroductionInterceptor
3 execution切点函数
execution函数用于匹配方法执行的连接点,语法为:
execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选))
参数部分允许使用通配符:
* 匹配任意字符,但只能匹配一个元素
.. 匹配任意字符,可以匹配任意多个元素,表示类时,必须和*联合使用
+ 必须跟在类名后面,如Horseman+,表示类本身和继承或扩展指定类的所有类
示例中的* chop(..)解读为:
方法修饰符 无
返回类型 *匹配任意数量字符,表示返回类型不限
方法名 chop表示匹配名称为chop的方法
参数 (..)表示匹配任意数量和类型的输入参数
异常模式 不限
更多示例:
void chop(String,int)
匹配目标类任意修饰符方法、返回void、方法名chop、带有一个String和一个int型参数的方法
public void chop(*)
匹配目标类public修饰、返回void、方法名chop、带有一个任意类型参数的方法
public String *o*(..)
匹配目标类public修饰、返回String类型、方法名中带有一个o字符、带有任意数量任意类型参数的方法
public void *o*(String,..)
匹配目标类public修饰、返回void、方法名中带有一个o字符、带有任意数量任意类型参数,但第一个参数必须有且为String型的方法
也可以指定类:
public void examples.chap03.Horseman.*(..)
匹配Horseman的public修饰、返回void、不限方法名、带有任意数量任意类型参数的方法
public void examples.chap03.*man.*(..)
匹配以man结尾的类中public修饰、返回void、不限方法名、带有任意数量任意类型参数的方法
指定包:
public void examples.chap03.*.chop(..)
匹配examples.chap03包下所有类中public修饰、返回void、方法名chop、带有任意数量任意类型参数的方法
public void examples..*.chop(..)
匹配examples.包下和所有子包中的类中public修饰、返回void、方法名chop、带有任意数量任意类型参数的方法
可以用这些表达式替换StorageAdvisor中的代码并观察效果
4 更多切点函数
除了execution(),Spring中还支持其他多个函数,这里列出名称和简单介绍,以方便根据需要进行更详细的查询
4.1 @annotation()
表示标注了指定注解的目标类方法
例如 @annotation(org.springframework.transaction.annotation.Transactional) 表示标注了@Transactional的方法
4.2 args()
通过目标类方法的参数类型指定切点
例如 args(String) 表示有且仅有一个String型参数的方法
4.3 @args()
通过目标类参数的对象类型是否标注了指定注解指定切点
如 @args(org.springframework.stereotype.Service) 表示有且仅有一个标注了@Service的类参数的方法
4.4 within()
通过类名指定切点
如 with(examples.chap03.Horseman) 表示Horseman的所有方法
4.5 target()
通过类名指定,同时包含所有子类
如 target(examples.chap03.Horseman) 且Elephantman extends Horseman,则两个类的所有方法都匹配
4.6 @within()
匹配标注了指定注解的类及其所有子类
如 @within(org.springframework.stereotype.Service) 给Horseman加上@Service标注,则Horseman和Elephantman 的所有方法都匹配
4.7 @target()
所有标注了指定注解的类
如 @target(org.springframework.stereotype.Service) 表示所有标注了@Service的类的所有方法
4.8 this()
大部分时候和target()相同,区别是this是在运行时生成代理类后,才判断代理类与指定的对象类型是否匹配
5 逻辑运算符
表达式可由多个切点函数通过逻辑运算组成
5.1 &&
与操作,求交集,也可以写成and
例如 execution(* chop(..)) && target(Horseman) 表示Horseman及其子类的chop方法
5.2 ||
或操作,求并集,也可以写成or
例如 execution(* chop(..)) || args(String) 表示名称为chop的方法或者有一个String型参数的方法
5.3 !
非操作,求反集,也可以写成not
例如 execution(* chop(..)) and !args(String) 表示名称为chop的方法但是不能是只有一个String型参数的方法
Spring Aspect切面类的使用相关推荐
- Spring @Aspect切面参数传递
Spring @Aspect切面参数传递: Xml: <?xml version="1.0" encoding="UTF-8"?> <bean ...
- Spring AOP切面使用详细解析
相关文章: SpringBoot AOP切面的使用 一步一步手绘Spring AOP运行时序图(Spring AOP 源码分析) 架构师系列内容:架构师学习笔记(持续更新)) Spring AOP 应 ...
- spring aop如何在切面类中获取切入点相关方法的参数、方法名、返回值、异常等信息
aop思想可以很好的帮助我们实现代码的解耦,比如我们之前提到的,将日志代码与业务层代码完全独立,通过spring aop的代理类进行整合.在切面类中,我们也能够通过spring提供的接口,很好的获取原 ...
- Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ
面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...
- spring调用切面失效分析(类内调用自身切面方法或其他切面方法失效)
spring调用切面失效分析(类内调用自身切面方法或其他切面方法失效) 简述 示例代码说明 演奏钢琴 观众鼓掌 执行程序及结果 原因分析 Spring切面原理 代码调试 fix bug 代码 结果 简 ...
- Spring AOP 切面(Aspect)应用详解
1. AOP 切面应用 下面是一个AOP切面的一个简单的应用实例 引入AOP依赖 <dependency><groupId>org.springframework.boot&l ...
- java切面类整合_SpringBoot2.x【五】整合AOP切面编程
SpringBoot2.x[五]整合AOP切面编程 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面. ...
- Spring 面向切面编程
AOP,也就是面向方面编程或者说面向面编程,是一种很重要的思想.在企业级系统中经常需要打印日志.事务管理这样针对某一方面的需求,但是传统的面向对象编程无法很好的满足这些需求.因此催生了面向切面编程这样 ...
- Spring AOP切面的时候参数的传递
Spring AOP切面的时候参数的传递 Xml: <?xml version="1.0" encoding="UTF-8"?> <beans ...
最新文章
- JS操作frame框架
- 每天一个linux命令(16):which命令
- Spark详解(十二):Spark Streaming原理和实现
- strncmp用法说明
- 隐马尔科夫模型C#语言算法实现
- 【OpenCV】OpenCV实战从入门到精通之 -- 离散傅里叶变换相关函数详解
- Spring事务嵌套
- C经典100题(1)
- 绿盟扫描出来的ubuntu12.04下apache漏洞修复
- 永川机器人博览会门票_14日 又到永川来看机器人哦
- VAM语料库--学习笔记
- 微信公众号广告市场如此之大,还不抓住这个淘金的好机会
- 2017-4-15,16
- FANUC机器人6点示教法设定工具坐标系的具体步骤
- 基于java(ssm)人事考勤签到管理系统源码(java毕业设计)
- 又一巨头从Java迁移到Kotlin:关键应用全部开始切换、安卓代码库超过千万行Kotlin代码
- keil 烧录时 Full Chip Erase Failed问题
- python----列表操作
- 这届程序YUAN可太优秀了
- Unity 之 接入腾讯Bugly简述【Android端】
热门文章
- iPhone iPad发展史
- uefi引导mbr分区表的win7,并与ubuntu18组双系统
- Linux各种文件系统支持单文件大小
- 【有机】祝介平课题组JACS:利用钯催化氧化[2+2]环化合成苯并环丁烯
- 每个python对象都具有布尔值、下列是true的是_根据企业所得税法律制度的规定,下列固定资产中,可以计提折旧扣除的是()。A.以融资租赁方式租出...
- Spring Boot实现MyBatis分页查询
- 禅宗经典名著----传心法要
- 如何把数据从阿里云迁移到华为云
- 2020年南京理工大学计算机推免面试
- vue路由重定向和动态路由