Open kun-song opened 6 years ago
OOP 和 AOP 都提升了模块化,两者相互补充,OOP 的模块化单元是 class,而 AOP 的模块化单元是 aspect。
Spring 两大基本功能:IOC 和 AOP,两者互相独立,无依赖关系。
Spring 中的 AOP 主要有两个作用:
Spring AOP 遵循 AOP 的概念和术语,没有另起炉灶,虽然 AOP 概念本身就不太直观。
Spring AOP 仅支持方法级的连接点,不支持字段级的连接点(AspectJ 支持),Spring AOP 更注重 AOP 与 IoC 容器的紧密集成,并非要提供完整的 AOP 实现。
在 Spring 中,AOP 一般与 IoC 一起使用,例如 Aspect 就可以定义为普通的 bean,可以随意注入使用,有些功能使用 Spring AOP 难以实现,这是很正常的,遇到这种问题,可以使用 AspectJ 而非 Spring AOP。
Spring AOP 默认实现为 JDK 标准动态代理,它可为任意接口实现代理,但是当遇到类是,JDK 内置的动态代理就无能为力了,此时 Spring AOP 将自动切换到 CGLIB 实现。
Aspect = Pointcut + Advice
在 Spring AOP 中,切面(Aspect)即用 @AspectJ
修饰的类,而 Spring AOP 仅支持方法级切点,所以切点就是方法,而 Advice 一般也是方法。
首先,需要开启 AspectJ 支持,参考 官方文档。
切面的声明非常简单,使用 @Aspect
修饰的类即为切面:
@Aspect
public class NotVeryUsefulAspect {
}
切点决定了在何处织入 Advice,使用 @Pointcut(...)
修饰的方法即为切点,其声明包含两部分:
void
@Pointcut
注解声明,匹配哪些连接点是需要织入 Advice 的@Pointcut("execution(* transfer(..))")// the pointcut expression
private void anyOldTransfer() {}// the pointcut signature
anyOldTransfer
切点将匹配所有名为 transfer
的方法Spring AOP 4.x.x 版本仅支持如下 AspectJ 切点指示符,其他的暂不支持:
execution
within
this
target
args
@args
@target
@within
@annotation
注意,切点表达式可以用 &&
||
和 !
进行组合:
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}
anyPublicOperation
匹配任意包中的 public
方法inTrading
匹配 com.xyz.someapp.trading
包中的任意方法若想匹配 com.xyz.someapp.trading
包中的 public
方法可以用 &&
组合:
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
anyPublicOperation()
类似方法调用
AOP,即面向切面编程,是 Spring 的两大基石功能之一(另一个是 DI 依赖注入,或控制反转)。
学习 AOP,有几个问题需要搞懂:AOP 是什么、为什么需要 AOP、如何实现 AOP?
AOP 是什么
我理解的 AOP:将特定代码片段,插入指定位置,从而实现功能增强。
为什么需要 AOP
AOP 实际是对 OO 的强力补充,既然是补充,那就说明传统的 OO 肯定存在某种问题。
OO 的核心概念是继承、封装与多态,其中:
其中,封装要求我们将业务逻辑分割为不同的、互相独立的类,每个类有自己独特的责任,这非常完美,每个类各司其责、互相独立,逻辑非常清晰,而且有助于代码复用。
但这种做法的前提是:应用 的确 可以分割为互相独立的逻辑单元,遗憾的是,这个假设本身就不成立,因为实际的应用中,不同类之间总会共享某些功能,例如日志、安全、事务等,最后导致不同类都在重复实现相同功能,反而不美。
AOP 解决的就是上面的问题,通过将共享代码片段,动态插入指定位置,可以去除业务类中的冗余代码,将共享代码集中维护,还能降低维护工作量。
如何实现 AOP
AOP 是一种通用思想,实现则与具体框架有关系,在 Java 世界中,常见的有 Spring AOP 和 AspectJ 两种框架。
使用 Spring 实现 AOP 可以参考其 官方文档,其中也包含对 AOP 概念的讲解,推荐。