本章内容:
- 面向切面编程的基本原理
- 通过POJO创建切面
- 使用@AspectJ注解
- 为AspectJ切面注入依赖
1.什么是面向切面编程
在软件开发中,散布于应用中多处的功能被称为横切关注点。通常来讲,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往会直接嵌入到应用的业务逻辑中)。把这些横切关注点与业务逻辑相分离正事面向切面编程(AOP)所要解决的问题
切面提供了取代继承和委托的另一种重用通用代码的方案,而且在很多的场景下更清晰简洁。在使用面向切面编程时,我们仍然在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面(aspect)。这样做有两个好处:首先,现在每个关注点都集中于一个地方,而不是分散到多处代码中;其次,服务模块更简洁,因为它们只包含主要关注点(或核心功能)的代码,而次要关注点的代码被转移到切面中
定义AOP术语:
通知(advice):通知定义了切面是什么以及何时使用
Spring切面可以应用5中类型的通知:
前置通知(before):在目标方法被调用之前调用通知功能
后置通知(after):在目标方法完成之后调用通知,此时不关心方法的输出是什么
放回通知(After-returning): 在目标方法成功执行之后调用通知
异常通知(After-throwing):在目标方法抛出异常后调用通知
环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
连接点(join point):
连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为
切点 (pointcut):
如果说通知定义了切面的“什么”和“何时”的话,那么切点就定义了“何处”。切点的定义会匹配通知所要织入的一个或多个连接点
切面(Aspect):
切面是通知和切点的结合。通知和切点共同定义了切面的全部内容---它是什么,在何时和何处完成其功能
引入(Introduction):
引入允许我们向现有的类添加新方法或属性,Spring不支持引入
织入(Weaving):
织入是把切面应用到目标对象并创建新的代理对象的过程。Spring是通过运行期为目标对象动态地创建一个代理对象实现的
Spring对AOP的支持:
Spring通知时Java编写的、Spring在运行时通知对象、Spring只支持方法级别的连接点
2.通过切点来选择连接点
编写切点:
我们使用execution()指示器选择Performance的perform()方法。方法表达式以“*”号开始,表明了我们不关心返回值的类型。然后,我们指定了全限定类名和方法名。对于方法参数列表,我们使用两个点(..)表明切点要选择任意perform()方法,无论该方法的人参是什么
在切点中选择bean:
除了以上所示的指示器外,Spring还引入了一个新的bean()指示器,它允许我们在切点表达式中是用bean的ID来标识bean。bean()使用bean ID或bean名称作为参数来限定切点只匹配特定的bean
3.使用注解创建切面
定义切面:类使用@AspectJ注解进行标注。该注解表明该类是一个切面
创建环绕通知:
环绕通知时最为强大的通知类型。它能够让你所编写的逻辑将被通知的目标方法完全包装起来。实际上就像在一个通知方法中同时编写前置通知和后置通知
处理通知中的参数:
在图4.6中需要关注的是切点表达式中的args(trackNumber)限定符。它表明传递给palyTrack()方法的int类型参数也会传递到通知中去。参数的名称trackNumber也与切点方法签名中的参数相匹配
这个参数会传递到通知方法中,这个通知方法是通过@Before注解和命名切点trackPlayed(trackNumber)定义的。切点定义中的参数与切点方法中的参数名称是一样的,这样就完成了从命名切点到通知方法的参数转移。