刚开始接触Spring AOP,编写的一个简单Demo使用基于AspectJ的注解形式添加了一个切面后,运行测试代码总是报错:
Error creating bean with name 'org.springframework.context.event.internalEventListenerProcessor': Initialization of bean failed;
error at ::0 can't find referenced pointcut performance
原因分析:
1)当切面类的方法上通知注解直接输入切入点表达式时,没有报错。切面类代码如下:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect//表明Audience类是一个切面
public class Audience {
//注解声明通知方法,()内的为切点表达式
@Before("execution(* concert.Performance.perform(..))")//通知方法在目标方法调用之前执行
public void silenceCellPhone(){
System.out.println("Silencing cell phones");
}
@Before("execution(* concert.Performance.perform(..))")
public void takeSeats(){
System.out.println("Taking Seats");
}
@AfterReturning("execution(* concert.Performance.perform(..))")//通知方法在目标方法返回后调用
public void applause(){
System.out.println("CLAP CLAP CLAP");
}
@AfterThrowing("execution(* concert.Performance.perform(..))")//通知方法会在目标方法抛出异常后调用
public void demandRefund(){
System.out.println("Demanding a refund");
}
//@After 通知方法会在目标方法返回或抛出异常后调用
//@Around 通知方法会将目标方法封装起来
}
2)当切面类的方法上通知注解引入定义的切入点,报错error at ::0 can't find referenced pointcut。切面类代码如下:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect//表明Audience类是一个切面
public class Audience {
//重构代码,用@PointCut注解在切面内定义一个可重用的切点
@Pointcut("execution(* concert.Performance.perform(..))")
public void performance(){}
@Before("performance()")//通知方法在目标方法调用之前执行
public void silenceCellPhone(){
System.out.println("Silencing cell phones");
}
@Before("performance()")
public void takeSeats(){
System.out.println("Taking Seats");
}
@AfterReturning("performance()")//通知方法在目标方法返回后调用
public void applause(){
System.out.println("CLAP CLAP CLAP");
}
@AfterThrowing("performance()")//通知方法会在目标方法抛出异常后调用
public void demandRefund(){
System.out.println("Demanding a refund");
}
//环绕通知方法
@Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp){
try{
System.out.println("round-Silencing cell phone");
System.out.println("round-Taking seats");
jp.proceed();
System.out.println("round-CLAP CLAP CLAP");
}catch (Throwable e){
System.out.println("round-Demanding a refund");
}
}
}
解决方案:
网上说是因为springAOP依赖aspectj的版本过低,也有说是JDK版本与aspectjrt.*.*.jar和aspectjweaver.*.*.jar不匹配的问题
本人用的JDK是1.7
项目添加了maven结构
在pom文件中添加下列依赖,亲测可用
<!-- https://mvnrepository.com/artifact/aopalliance/aopalliance -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>