簡體   English   中英

Spring:使用@Resource注入一個具體類需要CGLIB

[英]Spring: Is CGLIB required for injection of a concrete class using @Resource

我使用spring-instrument.jar和AspectJ LTW配置了Spring 3.0.6和:

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

從依賴項中刪除CGLIB時,即使創建了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?

經過3個多小時的代碼調查和更改Spring bean定義XML,我終於發現了問題。 這可以從stacktrace的這一部分找到,我在找到解決方案后注意到:

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

基於此處的注釋,我在<aop:config><aop:aspectj-autoproxy><tx:annotation-driven>中將所有proxy-target-class屬性更改為false,但沒有成功。

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

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

不,但需要創建AOP代理( 不能代理目標類 )。 你的班級有以下一個:

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

注釋? 或者也許這個類的方法有一些外在的方面? 盡管如此,AspectJ編譯器應該注意編織,不應該使用AFAIR CGLIB。 你能告訴我們你的代碼嗎?

在我的情況下,為了事務支持正確啟用加載時間編織,我必須添加:

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

看看一個有效的例子

如果您使用的是Spring APO,則需要包含CGLIB。 有兩種方法可以將其添加到項目中

  1. 下載CGLIB庫文件並將其添加到庫文件中。 http://www.java2s.com/Code/Jar/c/Downloadcglib22jar.htm
  2. 在pom.xml文件中添加Maven依賴項

    https://mvnrepository.com/artifact/cglib/cglib/2.2.2


<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2</version>
</dependency>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM