(1)Spring AOP
底层还是用的动态代理。如果目标对象所对应的类有接口,spring就用jdk生成代理对象;
如果目标对象所对应的类没有接口,spring就用CGLIB生成代理对象。
优点:动态代理,如果一个类被它代理,则接口或者类的所有方法都被强迫执行。而spring AOP可以按业务划分,有些方法需要事务则扩展功能,有些方法不需要则不进行扩展。
(2)相关概念词
① 切面aspect:切面是一个类(功能类),类里有若干方法,每个方法代表一个功能。把这些功能方法切到指定的位置,切到到业务方法的前后等
对应:spring中<aop:aspect id=“myAspect” ref=“tm”></aop:aspect>
② 连接点joinpoint:用代理对象调用方法,这句话的位置就是连接点,用连接点启动横切。
③ 通知advice:切面类中的那些方法就是通知。
前置通知<aop:before 在执行目标方法前面
后置通知<aop:after-returning 在执行完目标方法后执行
异常通知<aop:after-throwing 在目标方法抛异常执行,不会执行后置通知
最终通知<aop:after 前置,后置或异常通知,都执行完毕后会执行最终通知
环绕通知<aop:around 特点:可以控制目标方法的执行
④ 切入点pointcut:把切面中的通知,切到哪个类中的哪些方法上,切入点是指切到哪些方法上,spring给提供一些规则表达式,用于指定切在哪些方法上。
对应:spring中<aop:pointcut id=“myPointCut” expression=“execution(* com.hdu.service….(…))”/>
⑤ 目标对象targetObject:实际的业务类的对象
⑥ aop代理aopproxy:由spring框架帮程序员用jdk或cglib生成代理对象,这个生成的过程被spring封装了。spring的独有配置,用于指定生成代理对象。
对应: spring中aop:config</aop:config>
⑦ 织入weaving:也叫横切,把额外的功能用配置文件和注解的方式织入到业务中;取消配置文件和注解,就取消了织入,不影响原有业务流程
在spring中加入<aop:config节点,<aop:pointcut expression="",从spring容器取出expression属性指定的对象都是代理对象。
在spring中没有加入<aop:config节点,从spring容器中取出的所有对象是真实对象。
(3)参考手册
1、声明一个切面
2、声明一个切点
其中aop:pointcut/标签写在aop:aspect</aop:aspect>标签内,为局部切点,只起作用在对应切面。
其中aop:pointcut/标签写在aop:aspect</aop:aspect>标签外,为全局切点,所有切面对其有效。
关于切点的expression 表达式:
参考手册中的示例:
① the execution of any public method:所有的public方法
execution(public * *(..))
② the execution of any method with a name beginning with "set": 所有以set开头的方法
execution(* set*(..))
③ the execution of any method defined by the AccountService interface: com.xyz.service.AccountService类或接口中任意方法,任意参数,任意返回值
execution(* com.xyz.service.AccountService.*(..))
④ the execution of any method defined in the service package: com.xyz.service包下任意类,任意方法,任意参数,任意返回值
execution(* com.xyz.service.*.*(..))
⑤ the execution of any method defined in the service package or a sub-package: com.xyz.service包下以及子包下任意类.任意的方法,任意参数,任意返回值
execution(* com.xyz.service..*.*(..))
关于切点的within表达式:
① any join point (method execution only in Spring AOP) within the service package: com.xyz.service的任意类
within(com.xyz.service.*)
② any join point (method execution only in Spring AOP) within the service package or a sub-package: com.xyz.service及其子包下的任意类
within(com.xyz.service..*)
③ any join point (method execution only in Spring AOP) where the proxy implements the AccountService interface: com.xyz.service的AccountService类
this(com.xyz.service.AccountService)
3、声明通知
通常 前置通知、后置通知、异常通知、最终通知 与 环绕通知分开使用,否则执行顺序不符合预期逻辑。
若环绕通知叠加使用,按配置顺序先A后B,则执行时,先执行A在目标对象调用方法之前的内容,再执行B在目标对象调用方法之前的内容,调用目标对象的原有方法,执行A在目标对象调用方法之后的内容,执行B在目标对象调用方法之后的内容。
前置通知:
后置通知
异常通知
最终通知
环绕通知