这是我参与更文挑战的第18天,活动详情查看:更文挑战
Spring框架2.0版本发布后,Spring AOP增加了新的特性,或者说增加了新的使用方式。
- 支持AspectJ5发布的@AspectJ形式的AOP实现方式。现在,我们可以直接使用POJO来定义Aspect以及相关的Advice,并使用一套标准的注解标注这些POJO。Spring AOP会根据注解信息查找相关的Aspect定义,并将其声明的横切逻辑织入当前系统。
- 简化了的XML配置方式。现在,使用新的基于XSD的配置方式,我们可以使用aop独有的命名空间,并且注册和使用POJO形式实现的AOP概念实体。因为引入了AspectJ的Pointcut描述语言,也可以在新的配置方式中使用AspectJ形式的pointcut表达式。
@AspectJ代表一种定义Aspect的风格,它让我们能够以POJO的形式定义Aspect,没有其他接口定义限制。唯一需要的,就是使用相应的注解标注这些Aspect定义的POJO类。之后,Spring AOP会根据标注的注解来搜索这些Aspect定义类,然后将其织入系统。
这种方式是从AspectJ所引入的,定义的Aspect类基本上可以在Spring AOP和AspectJ之间通用。不过Spring AOP只使用了AspectJ的类库进行Pointcut的解析和匹配,最终的实现机制还是Spring AOP的架构,也就是使用代理模式处理横切逻辑的织入。下面让我们看看@AspectJ是如何使用的。
如果将之前的PerformanceMethodInterceptor定义的横切逻辑以@AspectJ形式实现,首先得定义一个Aspect,以最普通的POJO来定义这个Aspect就可以。按照@AspectJ形式重构后的PerformanceMethodInterceptor定义,代码如下:
@Aspect
public class PerformanceTraceAspect {
@Pointcut("execution(public void *.method1()) || execution(public void *.method2())")
public void pointcutName(){}
@Around("pointcutName()")
public Object performanceTrace(ProceedingJoinPoint joinpoint) throws Throwable {
StopWatch watch = new StopWatch();
try {
watch.start();
return joinpoint.proceed();
}
finally {
watch.stop();
}
}
}
复制代码
定义这么一个Aspect,我们再也无需像1.x时代的Spring AOP那样实现相应的接口了,现在唯一要做的就是为这个Aspect类加上一个@Aspect的注解。这样,稍后我们可以根据这个@Aspect,来判断Classpath中哪些类是我们要找的Aspect定义。
我们知道,Aspect中可以定义多个pointcut以及多个Advice,所以,除了要使用@Aspect标注Aspect类之外,还需要通过名为@Pointcut的注解指定Pointcut定义,通过@Around等注解来指定哪些方法定义了相应的Advice逻辑。
假设我们有如下目标对象类定义:
public class Foo {
public void method1() {
System.out.println("method1 execution.");
}
public void method2() {
System.out.println("method2 execution.");
}
}
复制代码
现在有两种方式将Aspect定义织入这个目标对象类,实现对其符合Pointcut定义的Joinpoint进行拦截。
1.编程方式织入
AspectJProxyFactory weaver = new AspectJProxyFactory();
weaver.setProxyTargetClass(true);
weaver.setTarget(new Foo());
weaver.addAspect(PerformanceTraceAspect.class);
Object proxy = weaver.getProxy();
(Foo)proxy.method1();
(Foo)proxy.method2();
复制代码
2.通过自动代理织入
针对@AspectJ风格的AOP,Spring AOP专门提供了一个AutoProxyCreator实现类进行自动代理,以免去过多编码和配置的工作,这个AutoProxyCreator之前提到过,即org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator。它是在AbstractAdvisorAutoProxyCreator的基础上给出的一个扩展类,它的直接父类是AspectJAwareAdvisorAutoProxyCreator。
与使用其他AutoProxyCreator一样,我们只需要在IoC容器的配置文件中注册一下AnnotationAwareAspectJAutoProxyCreator就可以了,配置如下:
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
<property name="proxyTargetClass" value="true"></property>
</bean>
复制代码
现在,AnnotationAwareAspectJAutoProxyCreator会自动搜集IoC容器中注册的Aspect,并应用到Pointcut定义的各个目标对象上。