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:

相当于:

posted @ 2019-05-24 18:38  yuby  阅读(174)  评论(0编辑  收藏  举报