我試圖使用AspectJ,我的項目工作正常。但是當我嘗試使用AspectJ時,注射不能正常工作。如果我不使用AspectJ,它會再次運行。AspectJ和NoSuchBeanDefinitionException至少有1個bean有資格作爲此依賴關係的自動導向候選者
我包括我的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>
我的配置文件:
<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" />
我使用註釋來我的班:
@Repository("RoomDAO")
public class RoomDAO extends JdbcDaoSupport implements IRoomDAO{
@Autowired
private PlayerDAO playerDAO;
我不知道如果我必須掃描我的AspectJ課程,我無論如何。我試圖標記爲required = false PlayerDAO,我可以檢查LoggingAspect是否被調用,但是當RoomDAO打算調用PlayerDAO時,我得到了一個NullPointException異常。爲什麼不能在我使用AspectJ的時候彈出注入PlayerDAO?
@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("******");
}
這是錯誤:
04-jun-2013 11:36:46 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.s[email protected]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
謝謝。
UPDATE:
我固定它添加
<aop:aspectj-autoproxy proxy-target-class="true"/>
但是,我不知道爲什麼發生這種情況,我很感激,如果有人可以解釋我。
有一件事我看到可能會影響它的是,你的autowire應該使用接口IPlayerDAO,而不是實現。我相信當Spring創建代理時,它使用接口來構建它,然後調用實例化的類。我將這一觀察僅僅基於我在自己的代碼中看到的堆棧跟蹤,所以我可能是錯的。 – CodeChimp
哦!非常感謝!你是對的。我刪除了autoproxy標籤,它正在工作。 – Guille
@CodeChimp:非常感謝你的解決方案,我有同樣的問題,花了幾天的堅果,終於找到了這篇文章.... :) –