繁体   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