springAOP
aop相关概念:
Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Pointcut(切点):表示一组 joint point,通过逻辑关系组合起来,或是通过通配、正则表达式等方式将joint point (符合规则的joint point )集中起来,它定义了相应的 Advice 将要发生的地方。
Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
Target(目标对象):织入 Advice 的目标对象 .。
Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
比如给感冒的人打针,每个人都是一个Joint point,但是我们只需要给感冒的人打针,所以我们根据感冒这个规则,将符合这些规则的人聚集起来形成一个Pointcut,而打针这个动作就是Advice 。
使用@Before在切入点开始处切入内容
使用@After在切入点结尾处切入内容,不考虑其结果,执行通知
使用@AfterReturning在切入点结尾处(只有在方法成功完成时,才能执行通知)切入内容(可以用来对处理返回值做一些加工处理),没有任何返回值也会执行此方法,返回值为null();
使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
先执行@Before,然后执行具体方法,然后执行@After,再执行@AfterReturning,抛出异常就执行@AfterThrowing
1.基于xml的aop:
需要先在xml文件里引入aop命名空间:
过程:
先声明一个aspect:
ref=“”代表当前aspect需要执行相应的advice时,去哪个类里面寻找对应的方法
声明一个切点:
expression用来定义讲那些join point聚合在一起的规则,或者说哪些join point需要执行advice
声明一个advice
你可以使用 <aop:{ADVICE NAME}> 元素在一个 中声明五个建议中的任何一个(before【在一个方法执行之前,执行通知】,after【在一个方法执行之后,不考虑其结果,执行通知。】,after-returning【在一个方法执行之后,只有在方法成功完成时,才能执行通知。】,after-throwing【在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。】,around【在建议方法调用之前和之后,执行通知。】),如下所示:
method(打针)代表当前adivce执行aspectConfig(<aop:aspect ref>执行的bean)中的哪个方法,pointcut-ref指向我们声明过的<aop:pointcut>,代表在当前pointcut(感冒)中的joint point(人)执行此方法,也可以使用pointcut属性直接指定:
expression配置说明:expression=“execution(修饰符 返回值 包名.类名/接口名.方法名(参数列表))”
*表示任意值,修饰符不能用*代替,返回值,方法名,参数必须有,参数列表(**)代表任意数量任意类型的参数,(*)代表一个任意类型的参数,(*,String)代表第一个参数为任意类型,第二个为String
public声明的方法,第一个*代表任意类型的返回值,第二个*代表任意方法名,(..)代表任意数量的参数
第一个*代表任意类型的返回值,set* 代表一set开头的任意方法名,(..)代表任意数量的参数
第一个*代表任意类型的返回值,com.app.model.HelloWorld代表HelloWorld这个bean下面的方法,第二个*代表任意方法,(..)代表任意数量的参数
代表com.app.model包下面的所有的类的所有方法(包下面的包不起作用)
代表com.app.model包和所有的子包下面的所有类的所有方法
代表com.app.model包和所有的子包下面的所有类的所有方法
代表com.app.model包和所有的子包下面的HelloWorld的所有方法
代表com.app.model包和所有的子包下面的以Hello开头的所有类的所有方法,把*和Hello替换位置,代表com.app.model包和所有的子包下面的以Hello结尾的所有类的所有方法
在多个表达式之间使用 ||,or表示 或,使用 &&,and表示 与,!表示非
2.基于注解的aop
首先需要xml配置文件中配置如下:
通过aop命名空间的<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。
当然,spring在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理
相当于
相当于
相当于
或者直接在advice上面指定pointcut:
相当于: