众所周知,spring听的最多的就是aop与ioc。所以切面是日常编程中运用相当频繁的东西。
我最开始写切面的时候,用的框架还是ssh。在xml配置文件中写了一堆东西。现在我自己也记不住怎么写了。
我感觉身为一个程序猿记忆很重要,因为这一行业你必须要学习很多东西,那就势必要记住很多东西。然而,我是善忘的。我记性差到昨天写的代码,今天去看可能都要想一哈当时为啥这里要用个if。所以,代码注释,于你于他人都很重要。所以,我写些常用的,基本的就是为了以后需要的时候不用再去翻代码亦或是问度娘。
下面,进入主题。
1.这是一个记录操作日志切面。代码如图一:
首先要定义切入点,就是你要拦截的方法。xml配置与其大同小异,思想都是一样的,无外乎一个是xml,一个是注解。
定义切入点之后,就是定义这个切入点的执行时机即在拦截方法之前执行或之后执行或其他时候执行,以及执行时的具体要干的事。
到这里就可以说切面就算完成了,老实说确实比较简单。
异常的处理,切面只是一个辅助,所以这一异常必须内部消化,不能因为切面bug了,咱主体功能就不要了吧。平时工作中要分清主次,异常是否影响主体进程,这个是具体业务具体分析的。
下面再说一哈其他问题,从上面图一的代码可以看出,一个是正常的日志,一个是异常日志。虽然正常的日志里面有个判断,那是因为这个导入数据的拦截切面,正常导入有两种情况,一是完美导入进数据库,二是导入时数据校验未通过。所以正常导入存在了一个if。
这里主要要说的是@AfterThrowing注解的使用。我故意让程序抛出异常,发现虽然进入异常拦截切面,但是异常日志却并未存入数据库。经询问度娘得知是因为aop事务优先级。所以,为了正常记录异常日志,需要在切面上加上@order注解,值越小优先级越高。没有看代码的同学可以翻上去瞅瞅。
经过测试,只有将@order注解的值设为integter最大值时,异常日志记录才失效。所以切面随便怎么设值,都是可以记录异常日志的。
最后,我想通过设置order的方式去改变被拦截方法的优先级,发现没有成功。度娘也没问到答案。需要去手动设置被拦截方法优先级的场景应该比较少,遇到了再问。至此切面的简单运用记录完成。
二 注解说明
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
三 execution切点函数
execution函数用于匹配方法执行的连接点,语法为:
execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选))
参数部分允许使用通配符:
* 匹配任意字符,但只能匹配一个元素
.. 匹配任意字符,可以匹配任意多个元素,表示类时,必须和*联合使用
+ 必须跟在类名后面,如Horseman+,表示类本身和继承或扩展指定类的所有类
示例中的* chop(..)解读为:
方法修饰符 无
返回类型 *匹配任意数量字符,表示返回类型不限
方法名 chop表示匹配名称为chop的方法
参数 (..)表示匹配任意数量和类型的输入参数
异常模式 不限