2011-11-17 28 views
4

我已經使用彈簧instrument.jar配置彈簧3.0.6用AspectJ LTW的具體類的注射CGLIB和:彈簧:是否需要使用@Resource

<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 

當從依賴除去CGLIB,我m到處甚至爲myBean後下面的異常創建(和它的@PostConstruct運行):

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'crawlItemService' defined in file [/path/to/project/foo/bar/MyBean.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435) 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409) 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:541) 
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:147) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84) 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:297) 
    ... 72 more 
Caused by: org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces. 
    at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67) 
    at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104) 
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    ... 83 more 

這是否意味着我應該有CGLIB即使在負載時織的存在呢?

+0

你進行代理的接口或類? – stivlo

+0

它是具體的類,如上所述。 – Mohsen

+0

Spring爲所有更現代的功能使用CGLIB。沒有它你不會走得太遠。 – skaffman

回答

10

經過3個多小時的代碼調查和更改Spring bean定義XML之後,我終於找到了問題。這可以從堆棧跟蹤其中的一部分,這是我找到的解決方案後發現發現:

at org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor.postProcessAfterInitialization(AsyncAnnotationBeanPostProcessor.java:126) 

基礎上的說明here,我改變了所有代理的目標類屬性爲false <aop:config><aop:aspectj-autoproxy><tx:annotation-driven>,但沒有成功。

然後我開始刪除我的XML定義的一部分,以找到哪一個修復這個問題。評論<task:annotation-driven>幫助解決了問題。然後我看到這個元素有一個mode屬性,我沒有指定,所以使用它的默認值proxy,所以需要CGLIB。正如我改變mode="aspectj"問題解決:

<task:annotation-driven scheduler="dataProviderScheduler" executor="dataProviderExecutor" mode="aspectj" /> 
+0

偉大的發現,+1!那麼你有沒有在某處使用'@ Async'註釋?不應該爲沒有這種方法的類生成CGLIB代理。 –

+0

謝謝,是的,我有@ @ Async'。如果您的異步方法不是從同一個bean中的另一個方法調用的,則CGLIB使用「@ Async」。 (這是CGLIB的一個已知問題)但是,當您從源bean注入的另一個bean調用異步方法時,它會起作用。 – Mohsen

3

不,但需要創建AOP代理(無法代理目標類)。您是否有類之一:

  • @Transactional
  • @Cacheable
  • @Async
  • ...

註解?或者,這個類的方法可能存在一些外部方面?儘管如此,AspectJ編譯器應該注意編織,不應使用AFAIR CGLIB。你能告訴我們你的代碼嗎?

在我的情況下才能正常啓用負載時間編織的事務支持我不得不添加:

<context:load-time-weaver/> 
<tx:annotation-driven mode="aspectj"/> 
<aop:config proxy-target-class="true"/> 

看一看一個working example

+0

我在MyBean上有@Transactional。還有:。這仍然需要CGLIB嗎? – Mohsen

+1

看我的編輯。也可以快速閱讀關於proyxing和交易的[文章](http://nurkiewicz.blogspot.com/2011/10/spring-pitfalls-proxying.html)。 –

+0

您確定嗎:。文檔說:屬性:proxy-target-class 是否創建基於類的(CGLIB)代理?默認情況下,創建標準的 基於Java接口的代理。 – Mohsen