1.什么是面向切面编程
在软件开发中,散布于应用中多处的功能被称为横切关注点,这些横切关注点从概念上是与应用的业务逻辑相分离的,但往往分直接嵌入到应用的业务逻辑之中,把这些横切关注点与业务逻辑相分离正式面向切面(AOP)要解决的问题。DI有助于应用对象之间的解耦,而AOP可以实现横切关注点与它们所影响的对象之间的解耦。
例如,安全是一个横切关注点,应用中许多方法都会涉及到安全规则,如果要重用通用功能的话,常见的面向对象技术是继承或委托,但是继承往往会导致一个脆弱的对象体系,而使用委托可能需要对委托对象进行复杂的调用。切面提供了一种替代方案,在使用面向切面编程时,我们仍然在一个地方定义通用功能,但是通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面(aspect)。这样做有两个好处,首先每个关注点都集中于一个地方,而不是分散到多处代码中,其次,应用只包含它们的业务逻辑代码,安全、事务管理等被转移到切面中了。
AOP常用的术语有通知(advice)、切点(pointcut)和连接点(joinpoint)。切面的工作被称为通知,通知描述了切面要完成的工作和何时执行这个工作,Spring切面可以应用5种类型的通知:
- 前置通知(Before):在目标方法被调用之前调用通知功能
- 后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么
- 返回通知(After-returning):在目标方法成功执行之后调用通知
- 异常通知(After-throwing):在目标方法抛出异常后调用通知
- 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
应用通知的时机被称为连接点,连接点是在应用执行过程中能够插入切面的一个点,这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。
切点定义了“何处”应用通知,切点的定义会匹配通知要织入的一个点或多个连接点,我们通常使用明确的类和方法名称或利用正则表达式定义所匹配的类和方法名称指定这些切点,有些AOP框架允许创建动态的切点,可以根据运行时的决策决定是否应用通知。
切面是通知和切点的结合,通知和切点共同定义了切面的全部内容,它是什么,在何时和何处完成其功能。
引入(Introduction)允许我们向现有的类添加新方法或属性,我们可以创建一个通知类,该类通过一个实例变量和Setter方法记录了对象最后一次修改时的状态。然后这个新方法和实例变量就可以被引入到现有的类中,从而在无需修改现有的类的情况下,使它们具有新的行为和状态。
织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中,在目标对象的生命周期有多个点可以进行织入:编译期、类加载期、运行期,Spring AOP是在应用运行时织入的。