2011-11-17 94 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