问题描述
在使用Spring通过注解方式实现AOP时报出循环依赖错误 完整的报错信息:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'logAspects': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.aop.aspectj.annotation.BeanFactoryAspectInstanceFactory.getAspectInstance(BeanFactoryAspectInstanceFactory.java:90)
at org.springframework.aop.aspectj.annotation.LazySingletonAspectInstanceFactoryDecorator.getAspectInstance(LazySingletonAspectInstanceFactoryDecorator.java:56)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.xopencode.spring.aop.MainConfigOfAOP$$EnhancerBySpringCGLIB$$638b0922.logAspects(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 67 more
原因分析:
1.既然报错信息中明确的指出创建名‘logAspects’的bean出现循环依赖,那么我们直接锁定LogAspects的内容
其中我LogAspects类的创建时放在config配置类中进行声明
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
LogAspects类完整信息
package com.xopencode.spring.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
@Aspect
public class LogAspects {
@Pointcut("execution(* com.xopencode.spring.aop.*.*(..))")
public void pointCut() {
}
@Before("pointCut()")
public void logStart(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
System.out.println("前置---" + joinPoint.getSignature().getName() + "运行。。。@Before:参数列表是:{" + Arrays.asList(args) + "}");
}
@After("com.xopencode.spring.aop.LogAspects.pointCut()")
public void logEnd(JoinPoint joinPoint) {
System.out.println("最终---" + joinPoint.getSignature().getName() + "结束。。。@After");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void logReturn(JoinPoint joinPoint, Object result) {
System.out.println("后置---" + joinPoint.getSignature().getName() + "正常返回。。。@AfterReturning:运行结果:{" + result + "}");
}
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void logException(JoinPoint joinPoint, Exception exception) {
System.out.println("异常---" + joinPoint.getSignature().getName() + "异常。。。异常信息:{" + exception + "}");
}
@Around("pointCut()")
public Object logAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Around: 执行目标方法之前");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("Around: 执行目标方法之后");
return proceed;
}
}
通过查看可以发现,大部分内容都为通知增强的声明,而可能会出现循环依赖就只有切点声明部分了
@Pointcut("execution(* com.xopencode.spring.aop.*.*(..))")
public void pointCut() {}
类路径: 通过对比发现,切点路径也把Aspect切点声明类也包含进去了。
解决方案:
- 把切点表达式路径定位至某个aop被增强类中
@Pointcut("execution(* com.xopencode.spring.aop.MathCalculator.*(..))")
public void pointCut() {}
- 把Aspect切面增强类移到其他路径
|