在上篇中,我们从写死代码,到使用代理;从编程式 Spring AOP 到声明式 Spring AOP,
AOP 那点事儿(续集)
。一切都朝着简单实用主义的方向在发展。沿着 Spring AOP 的方向,Rod Johnson(老罗)花了不少心思,都是为了让我们使用 Spring 框架时不会感受到麻烦,但事实却并非如此。那么,后来老罗究竟对 Spring AOP 做了哪些改进呢?现在继续!
9. Spring AOP:切面
之前谈到的 AOP 框架其实可以将它理解为一个 框架,但这个 似乎非常武断。比如说,如果它拦截了一个类,那么它就拦截了这个类中所有的方法。类似地,当我们在使用动态代理的时候,其实也遇到了这个问题。需要在代码中对所拦截的方法名加以判断,才能过滤出我们需要拦截的方法,想想这种做法确实不太优雅。在大量的真实项目中,似乎我们只需要拦截特定的方法就行了,没必要拦截所有的方法。于是,老罗同志借助了 AOP 的一个很重要的工具,Advisor(切面),来解决这个问题。它也是 AOP 中的核心!是我们关注的重点!
也就是说,我们可以通过切面,将增强类与拦截匹配条件组合在一起,然后将这个切面配置到 ProxyFactory 中,从而生成代理。
这里提到这个“拦截匹配条件”在 AOP 中就叫做 Pointcut(切点),其实说白了就是一个基于表达式的拦截条件罢了。
归纳一下,Advisor(切面)封装了 Advice(增强)与 Pointcut(切点 )。当您理解了这句话后,就往下看吧。
我在 GreetingImpl 类中故意增加了两个方法,都以“good”开头。下面要做的就是拦截这两个新增的方法,而对 sayHello() 方法不作拦截。
@Componentpublic class GreetingImpl implements Greeting { @Override public void sayHello(String name) { System.out.println("Hello! " + name); } public void goodMorning(String name) { System.out.println("Good Morning! " + name); } public void goodNight(String name) { System.out.println("Good Night! " + name); }}
在 Spring AOP 中,老罗已经给我们提供了许多切面类了,这些切面类我个人感觉最好用的就是基于正则表达式的切面类,
电脑资料
《AOP 那点事儿(续集)》(http://meiwen.anslib.com)。看看您就明白了:<b><b><b></bean></bean></beans>
使用 元素来进行 AOP 配置,在其子元素中配置切面,包括增强类型、目标方法、切点等信息。
无论您是不能使用注解,还是不愿意使用注解,Spring AOP 都能为您提供全方位的服务。
好了,我所知道的比较实用的 AOP 技术都在这里了,当然还有一些更为高级的特性,由于个人精力有限,这里就不再深入了。
还是依照惯例,给一张牛逼的高清 思维导图,总结一下以上各个知识点:
再来一张表格,总结一下各类增强类型所对应的解决方案:
增强类型基于 AOP 接口基于 @Aspect基于Before Advice(前置增强)MethodBeforeAdvice@BeforeAfterAdvice(后置增强)AfterReturningAdvice@AfterAroundAdvice(环绕增强)MethodInterceptor@AroundThrowsAdvice(抛出增强ThrowsAdvice@AfterThrowingIntroductionAdvice(引入增强)DelegatingIntroductionInterceptor@DeclareParents最后给一张 UML 类图描述一下 Spring AOP 的整体架构: