实现基于Spring AspectJ的注释(JavaConfig)

时间:2015-01-26 21:46:05

标签: java spring exception aspectj spring-aop

我们正在尝试将AspectJ @Aspect实施到我们现有的软件中,以便在进行服务调用后执行某些代码。

注意:

  • 我们的服务接口和实现为@Autowired 整个项目通过休息控制器以及其他服务实施。
  • 这个项目完全是一个没有XML的Java配置。
  • 我们正在使用部署在Tomcat 7.0.54上的Spring 4.1.2 RELEASE。

问题:

当我们将@EnableAspectJAutoProxy添加到主@JavaConfig时,我们会遇到以下异常:

  

无法解决的循环参考。

对于很长的bean列表,每次@Autowired尝试失败。

尝试:

  • 删除了@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?

1 个答案:

答案 0 :(得分:1)

这完全是我们的Spring配置的问题。我们的Spring Security配置在我们的主应用程序配置处理过程中仍在尝试@Autowired bean。我们通过确保在主@Configuration之后配置Spring Security来解决这个问题。

@Override
public void onStartup(ServletContext container) throws ServletException {
    AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
    // Initialize web mvc
    appContext.setDisplayName("APP");
    appContext.register(WebConfig.class);
    appContext.register(SecurityConfig.class);

    // Rest omitted (listeners, dispatcher servlet, etc.)
}