Spring

AOP总结

AOP:Aspect Oriented Programming,面向切面编程。

AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。

  1. AspectJ是静态代理,也称为编译时增强,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
  2. Spring AOP使用的动态代理(主要有两种方式,JDK动态代理和CGLIB动态代理。如果被代理的类有接口,就JDK动态代理;否则选择CGLIB动态代理),所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

AspectJ vs Spring AOP

Spring-AOP Pros

  • 比AspectJ更简单,不需要使用Load-Time Weaving以及AspectJ编译器(为了Compile-Time Weaving)
  • 当使用@Aspect注解时可以很方便的迁移到AspectJ AOP实现
  • 使用代理模式和装饰模式

Spring-AOP Cons

  • 由于是基于代理的AOP,所以基本上只能选择方法execution这一个Pointcut原语
  • 在类本身中调用另一个方法的时候Aspects不会生效
  • 有一点运行时的额外开销
  • 无法为不是从Spring Factory中创建的对象添加Aspect(只对Spring Bean有效)

AspectJ Pros

  • 支持所有的Pointcut原语,这意味着你可以做任何事情
  • 运行时开销比Spring AOP少
  • 能够添加各种编译错误来保障代码质量(这一条是我自己添加的)

AspectJ Cons

  • 当心。检查是否发生了意料之外的Weaving操作
  • 使用Compile-Time Weaving时需要额外的构建步骤(使用AspectJ Compiler),在使用Load-Time Weaving时需要一些配置(-javaassist)

一、AspectJ

https://blog.csdn.net/dm_vincent/article/details/57526325

二、Spring AOP

专用名词

五种Advice的执行顺序

三、实现Spring AOP

实现 Spring AOP 的方式,主要有两大类:

  • JDK动态代理方法:使用JDK动态代理技术,利用增强方法的方式,对该方法进行装饰,以取代原有对象行为的执行。
  • SpringAPI静态织入方法:引入特定的语法创建"切面",从而使得编译器可以在编译期间织入有关"切面"的代码。

1-JDK动态代理方法

详见:设计模式 - 静态代理 VS 动态代理

2-SpringAPI静态织入

2.1-导入AOP织入包 aspectjweaver

2.2- 构建切面Aspect (即写log的工具类),目标Target(即目标类)

切面:

 

  

 目标类:

2.3-applicationContext.xml中配置aop

***重点*** execution表达式

execution(修饰符  返回值  包名.类名/接口名.方法名(参数列表))

*代表所有可能的类型

(..)可以代表所有参数,(*)代表一个参数,(*,String)代表第一个参数为任何值,第二个参数为String类型.

示例:execution(* * com.kuang.service.UserServiceImpl.*(..))

  • 第一个 * 代表所有的修饰符,public,private, protected均可
  • 第二个 * 代表所有的修饰符,public,private, protected均可 
  • com.kuang.service 包名
  • UserServiceImpl 类名
  • UserServiceImpl.* 该类下的所有方法
  • UserServiceImpl.*(..) 该类下的所有参数类型的方法

3-自定义类静态织入(推荐)

***重要*** 自定义类静态织入 vs SpringAPI静态织入

SpringAPI织入方式,如果想加入 beforeAdvice 和 afterReturningAdvice,需要新两个类,单独的实现各自接口。

而自定义类植入方式,则可以统一放在一个类中,不需要实现任何SpringAPI接口,只在bean中指定对应方法即可。

4-注解实现(方便,容易记忆)

注意: @Around有一个必须要的参数ProceedingJoinPoint jp, 在方法内部还必须显示调用jp.proceed()

参考

视频:注解方式实现AOP + 切入点表达式

视频:XML方式实现AOP

原文地址:https://www.cnblogs.com/frankcui/p/13912482.html