使用注入AspectJ的方式实现切面
虽然Spring AOP能够满足许多应用的切面需求,但是与AspectJ相比,Spring AOP 是一个功能比较弱的AOP解决方案。AspectJ提供了Spring AOP所不能支持的许多类型的切点。
例如,当我们需要在创建对象时应用通知,构造器切点就非常方便。Spring基于代理的AOP无法把通知应用于对象的创建过程。
两部分内容
1. 使用注入aspect的方式创建切面
2. 注入的aspect方式跟其他3中方式的不同?把通知应用于对象的创建过程
1. 定义切面
package aop.kind4;
/**
* 定义切面
*/
public aspect CriticAspect {
public CriticAspect(){}
/**
* 定义切点
*/
pointcut performance():execution(* perform(..));
pointcut construct():execution(aop.kind4.CriticismEngineImpl.new());
after() returning : performance(){
System.out.println(criticismEngine.getCriticism());
}
after():construct(){
System.out.println("Performance 构造器结束");
}
before():construct(){
System.out.println("Performance 构造器开始");
}
private CriticismEngine criticismEngine;
public void setCriticismEngine(CriticismEngine criticismEngine){
this.criticismEngine = criticismEngine;
}
}
2. 定义CriticismEngine接口,并实现
package aop.kind4;
public class CriticismEngine {
public void setCriticism(String criticism) {
this.criticism = criticism;
}
private String criticism;
public String getCriticism() {
return criticism;
}
}
package aop.kind4;
public class CriticismEngineImpl extends CriticismEngine {
public CriticismEngineImpl(){}
private String[] criticismPool;
@Override
public String getCriticism(){
int i = (int)(Math.random() * criticismPool.length);
return criticismPool[i];
}
public void setCriticismPool(String[] criticismPool){
this.criticismPool = criticismPool;
}
}
CriticismEngineImpl实现了CriticismEngine接口,通过从注入的评论池中随机选择一个苛刻的评论。这个类可以使用如下的XML声明为一个Spring bean。
<bean id="criticismEngine" class="aop.kind4.CriticismEngineImpl">
<property name="criticismPool">
<list>
<value>Worst performance ever!</value>
<value>I laughed, I cried, then I realized I was at the wrong show.</value>
<value>A must see show!</value>
</list>
</property>
</bean>
<bean class="aop.kind4.CriticAspect" factory-method="aspectOf">
<property name="criticismEngine" ref="criticismEngine" />
</bean>
<bean id="performance" class="aop.kind4.TestPerformance" />
使用Spring的依赖注入为AspectJ切面注入协作者,那我们就需要在Spring配置中把切面声明为一个Spring配置中的<bean>。
因为Spring不能负责创建CriticAspect不能再Spring中简单的吧CriticAspect声明为一个bean。我们需要一种方式为Spring获得已经由AspectJ创建的CriticAspect实例的句柄,从而可以注入CriticismEngine。幸好,所有的AspectJ切面都提供了一个静态的aspectOf()方法,该方法返回切面的一个单例。所以为了获得切面的实例,我们必须使用factory-method来调用asepctOf()方法而不是调用CriticAspect的构造器方法。简而言之,Spring不能像之前那样使用<bean>声明来创建一个CriticAspect实例——它已经在运行时由AspectJ创建完成了。Spring需要通过aspectOf()工厂方法获得切面的引用,然后像<bean>元素规定的那样在该对象上执行依赖注入。
需要引入maven 包:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>