AspectJ and NoSuchBeanDefinitionException at least 1 bean which qualifies as autowire candidate for this dependency

I'm trying to use AspectJ, my project was working correctly. But when I try to use AspectJ the injection isn't working correctly. If I don't use AspectJ, it works again.

I included on my pom.xml

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.11</version>
        </dependency>

My configuration file:

   <aop:aspectj-autoproxy />
    <tx:annotation-driven />

    <!-- Database Configuration -->
    <import resource="../database/DataSource.xml"/> 

        <!-- Auto scan the components -->
    <context:component-scan base-package="es.rooms.db.spring.dao" />
    <context:component-scan base-package="es.rooms.util" />

    <!-- Aspect -->
    <bean id="logAspect" class="es.rooms.util.LoggingAspect" />

I'm using annotations to my classes:

@Repository("RoomDAO")
public class RoomDAO extends JdbcDaoSupport implements IRoomDAO{

    @Autowired
    private PlayerDAO playerDAO;

I don't know if I have to scan my AspectJ class, I did anyway. I tried to mark as required=false the PlayerDAO and I could check that LoggingAspect is called but when RoomDAO is going to call to PlayerDAO I got a NullPointException. Why can't spring inject PlayerDAO when I use AspectJ?

@Aspect
public class LoggingAspect {



    @Before("execution(* es.rooms.db.spring.dao.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {

        System.out.println("!!!!!!!!!!!!!!logBefore() is running! ->" + joinPoint.getSignature().getName());        
        System.out.println("******");
    }

This is the error:

04-jun-2013 11:36:46 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@61acfa31: defining beans [org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,playerDAO,RoomDAO,userDAO,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,manageRooms,messagesGcm,transactionManager,logAspect,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RoomDAO': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.rooms.db.spring.dao.PlayerDAO es.rooms.db.spring.dao.RoomDAO.playerDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [es.rooms.db.spring.dao.PlayerDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at es.rooms.server.RoomsServer.<init>(RoomsServer.java:23)
    at es.rooms.server.RoomsServer.main(RoomsServer.java:61)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private es.rooms.db.spring.dao.PlayerDAO es.rooms.db.spring.dao.RoomDAO.playerDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [es.rooms.db.spring.dao.PlayerDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    ... 14 more

Thank you.

UPDATE:

I fixed it adding

<aop:aspectj-autoproxy proxy-target-class="true"/>

But, i don't know why that happens, I appreciate if someone could explain me.

Answers


from http://docs.spring.io/spring/docs/3.1.1.RELEASE/spring-framework-reference/html/aop.html

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice).

If the target object to be proxied implements at least one interface then a JDK dynamic proxy will be used. All of the interfaces implemented by the target type will be proxied. If the target object does not implement any interfaces then a CGLIB proxy will be created.

If you want to force the use of CGLIB proxying (for example, to proxy every method defined for the target object, not just those implemented by its interfaces) you can do so. .... To force the use of CGLIB proxies set the value of the proxy-target-class attribute of the element to true:

So, you have turned on the CGLIB proxy for all your classes. Read the whole page for more information - it's important background info to using spring AOP. Some interesting and different things happen when you use CGLIB (all documented on the above link) - you're better off following the Spring conventions if you can. i.e. if you autowire a class, give it an interface and a null constructor.


I ended up with same error message in one unit test I used, by mistake:

@Autowire
ServiceImpl service;

instead of

@Autowire
Service service;

(where ServiceImpl was implementing Service). It was working with either version until I added aop:aspectj-autoproxy


Need Your Help

Boundary Fill Simulation (C++)

c++ recursion matrix divide-and-conquer boundary

I'm trying to simulate the Boundary Fill method with a matrix of integer, which in each position has a number from 0-255 that identifies the "pixel color" and I ask a position, a color to be change...