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

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

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.

回答1:

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.



回答2:

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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!