【发布时间】:2015-03-25 09:49:15
【问题描述】:
我们正在尝试将 AspectJ @Aspect 实现到我们现有的软件中,以便在进行服务调用后执行一些代码。
注意:
- 我们的服务接口和实现是
@Autowired通过休息控制器和其他服务实现贯穿整个项目。 - 这个项目完全是一个 Java 配置,没有任何 XML。
- 我们使用的是部署在 Tomcat 7.0.54 上的 Spring 4.1.2 RELEASE。
问题:
当我们将@EnableAspectJAutoProxy 添加到我们的主@JavaConfig 中时,我们遇到了以下异常:
无法解析的循环引用。
每次@Autowired 对一长串 bean 的尝试都会失败。
试过了:
- 删除了
@EnableAspectJAutoProxy注释,它可以正确自动连接所有内容,但我们的 @Aspect 永远不会被调用。 - 通过声明在注解中添加了 CGLIB 支持
proxytargetclass=true无济于事。 - 我们已尝试直接从 Spring 遵循此文档:@EnableAspectJAutoProxy Javadoc
这似乎是 AspectJ 的代理机制处理自动装配依赖项的问题。
当我们添加@EnableAspectJAutoProxy时为什么会出现这种情况?
我们的 Java 配置:
@Configuration
@EnableWebMvc
@EnableJpaRepositories(basePackages ={"com.company.product.persistence.repository"})
@EnableTransactionManagement
@EnableSwagger
@EnableAspectJAutoProxy
@PropertySource({"classpath:hibernate.properties",
"classpath:auth.properties",
"classpath:mail.properties",
"classpath:locations.properties"
})
@ComponentScan(basePackages = {"com.company.product"})
public class WebConfig extends WebMvcConfigurerAdapter {
//Bean declarations here.
//Note: All services/repos/controllers are annotation based.
}
方面实现:
@Aspect
@Component
public class PostMessageAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@After("execution(*com.company.product.persistence.serviceImpl.event.eventServiceImpl.methodCall(..))")
public void postMessageRun(final JoinPoint joinPoint) {
logger.info("CALLED AFTER METHOD");
}
}
更新:
设法让 AOP/AspectJ 在一台开发机器上完美运行,只需要对我们的 Spring Security 配置进行微小的更改。我们都在 Tomcat 7.0.56 的默认实例上运行的 Ubuntu 14.0.4 上使用 Intellij、openJDK 1.7.0_65。在另一台运行相同软件堆栈的机器上,获取以下内容。
堆栈跟踪:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatchingMessageController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.event.DispatchingEventService com.apx.efm.controllers.message.DispatchingMessageController.dispatchingEventService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatchingEventServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingAd dressesService com.apx.efm.persistence.serviceImpl.event.DispatchingEventServiceImpl.buildingAddressesService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'buildingAddressServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingService com.apx.efm.persistence.serviceImpl.building.BuildingAddressServiceImpl.buildingService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'buildingServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.apx.efm.persistence.service.building.BuildingAddressesService com.apx.efm.persistence.serviceImpl.building.BuildingServiceImpl.buildingAddressesService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.aopalliance.intercept.MethodInterceptor]: Factory method 'methodSecurityInterceptor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.apx.efm.persistence.service.user.EfmUserService com.apx.efm.application.config.SecurityConfig.efmUserService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'efmUserServiceImpl' defined in file [/home/apxdev4/Development/GitRepositories/efim-restful-web-service/target/EFIM/WEB-INF/classes/com/apx/efm/persistence/serviceImpl/user/EfmUserServiceImpl.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'methodSecurityInterceptor': Requested bean is currently in creation: Is there an unresolvable circular reference?
【问题讨论】:
-
您在构建可部署时是否调用了 aspectj 编译器?
-
@Hannes 我们关注了spring doc,在以下部分:9.2.1 启用 AspectJ 支持。
-
您发布的两个类的包名是什么?你有没有在你的方面省略任何注入的组件?
-
@kriegaex 方面组件没有任何遗漏。任何数据都在包持久性下。*(IE:持久性。[repository,service,serviceImpl,entity]。不确定这是如何相关的。请注意,由于隐私,包名称已被编辑。
-
我的意思是方面和配置类的包名。您有一个循环引用,例如组件 A 依赖于 B,B 依赖于 C,C 依赖于 A。隐私很好,但我们需要一些方法来重现问题。否则你需要一个人做。
标签: java spring exception aspectj spring-aop