AOP

概念总结

横切关注点: 一个个具体需求叫横切关注点,比如验证参数

切面:横切关注点模块化的对象,比如说验证参数这个需求的切面,感觉和横切关注点差不多。

通知切面里的每一个方法叫做通知,也就是切面里需要做什么,比如说验证切面可能有多个执行校验的函数。

目标:被切的对象,如上例中的ArithmeticCalculator类,切面的目的是对这个类进行校验参数,打印输入输出日志。

代理:在目标外面包了一层创建的类的对象。

连接点:可以说就是目标的方法上可以被切的地方,在方法的之前之后等时机代理都可以执行自定义的方法。比如ArithmeticCalculatoradd方法执行之前、之后、抛异常后,在这些时刻代理(即ArithmeticCalculator外面包的类)可以捕获到来执行通知

切点:用来匹配连接点的条件,比如一个切点会匹配所有抛异常的连接点。

JDK 动态代理对象 & CGLIB 代理对象

https://segmentfault.com/a/1190000007469968

一个类被 AOP 织入 advice, 就会产生一个结果类, 它是融合了原类和增强逻辑的代理类. 在 Spring AOP 中, 一个 AOP 代理是一个 JDK 动态代理对象或 CGLIB 代理对象.

将 aspect 和其他对象连接起来, 并创建 adviced object 的过程(即创建代理对象). 根据不同的实现技术, AOP织入有三种方式:

  • 编译器织入, 这要求有特殊的Java编译器.

  • 类装载期织入, 这需要有特殊的类装载器.

  • 动态代理织入, 在运行期为目标类添加增强(Advice)生成子类的方式. Spring 采用动态代理织入, 而AspectJ采用编译器织入和类装载期织入.

Spring AOP 默认使用标准的 JDK 动态代理(dynamic proxy)技术来实现 AOP 代理, 通过它, 我们可以为任意的接口实现代理. 如果需要为一个类实现代理, 那么可以使用 CGLIB 代理. 当一个业务逻辑对象没有实现接口时, 那么Spring AOP 就默认使用 CGLIB 来作为 AOP 代理了. 即如果我们需要为一个方法织入 advice, 但是这个方法不是一个接口所提供的方法, 则此时 Spring AOP 会使用 CGLIB 来实现动态代理. 鉴于此, Spring AOP 建议基于接口编程, 对接口进行 AOP 而不是类.

Last updated

Was this helpful?