proulxs
proulxs

Reputation: 508

Implementing annotation based Spring AspectJ (JavaConfig)

We're trying to implement AspectJ @Aspect into our existing software for executing some code after a service call is made.

Note:

Issue:

When we added @EnableAspectJAutoProxy into our main @JavaConfig, we experience the following exception:

Unresolvable circular reference.

Which fails every @Autowired attempt on a long list of beans.

Tried:

This seems to be an issue with AspectJ's proxy mechanism dealing with autowired dependencies.

Why does this occur when we add the @EnableAspectJAutoProxy?

Our Java Config:

@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 implementation:

@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");
    }
}

Update:

Managed to get AOP/AspectJ working perfectly fine on one dev machine only requiring a minor change to our Spring Security config. We are both using Intellij, openJDK 1.7.0_65 on Ubuntu 14.0.4 running on default instances of Tomcat 7.0.56. On the other machine running the same software stack, gets the following.

Stack Trace:

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?

Upvotes: 2

Views: 2448

Answers (1)

proulxs
proulxs

Reputation: 508

This was entirely an issue with our Spring configuration. Our Spring Security configuration was trying to @Autowired beans while they were still in the middle of being processed by our main application configuration. We solved this by ensuring that Spring Security gets configured after the main @Configuration.

@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.)
}

Upvotes: 1

Related Questions