@Aspect
@Component
public class ResponseTimeLoggerAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass().getCanonicalName());
@Around("requestHandlerMethod()")
public void logResponseTime(ProceedingJoinPoint point) {
long startTime = System.currentTimeMillis();
try {
point.proceed();
}
catch (Throwable e) {
}
long timeTaken = System.currentTimeMillis() - startTime;
logger.info(point.getSignature().getName() + " took " + timeTaken + " ms.");
}
@Pointcut("execution(* com.jms.JMSMessageListener.*(..))")
public void requestHandlerMethod() {}
}
@Configuration
@Import({JMSConfig.class, Neo4jConfig.class})
@ComponentScan(basePackageClasses=BeansPackageMarker.class)
@EnableAspectJAutoProxy
public class ApplicationConfig {
}
例外:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.jms.JMSMessageListener] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
如果我通过从ApplicationConfig中注释掉@EnableAspectJAutoProxy来禁用方面,则它不会引发任何异常,但不会执行AspectJ建议(如预期的那样).
在我看来,通过启用aspectJ,Spring意识到该建议适用于JMSMessageListener,因此它围绕它创建了一个代理,这就是为什么Spring无法自动装配JMSMessageListener bean的原因,因为现在该bean不存在,但是该bean上的代理已经存在那里.
解决方法:
正如@Evgeni正确指出的那样,它通过更改
@EnableAspectJAutoProxy
至
@EnableAspectJAutoProxy(proxyTargetClass=true)
启用基于CGLIB的代理(默认情况下启用基于DynamicJDK的代理)
目标类也必须具有默认构造函数.这是基于CGLIB的代理工作的要求.