2011-10-23 92 views
7

我有一個Spring應用程序 ,我做我的測試類,如下所示:爲什麼我需要cglib(Spring AOP)有多個測試類?

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback = true) 
@Transactional 
public class MyTest { 

} 

當我試圖創建另一個測試類,並試圖運行應用程序,我得到了新的測試以下異常類:

ERROR [main] (TestContextManager.java:324) - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecut 
[email protected]] to prepare test instance [[email protected]] 
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 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:386) 
     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:111) 
     at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
     at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:301) 
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) 
     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
     at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
     at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
     at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) 
     at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62) 
     at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) 
     at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) 
     at org.apache.maven.surefire.Surefire.run(Surefire.java:177) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) 
     at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) 

此異常中加入CGLIB到我的類路徑解決,但是我想知道爲什麼多個測試類需要CGLIB?

請指教,謝謝。

+0

你的「另一個測試」是否使用相同的'applicationContext.xml'? – axtavt

+0

是的,因爲我需要兩個測試來使用applicationContext.xml中存在的相同數據庫配置。 –

回答

10

春天需要CGLIB罐子,因爲它使用CGLIB來代理你的bean。如果將spring配置爲在applicationContext.xml中使用此機制,或者Spring需要代理實現無接口的類,則會發生這種情況。 Spring的文檔是here,並提供了一個非常明確的解釋。

爲了使用JDK動態代理確保任何代理類都實現了合適的接口,並且不要強制Spring通過配置使用CGLIB。

+1

CGLIB的需求「如果Spring需要代理一個沒有實現接口的類」對我來說是新聞。謝謝! – Snekse

1

我的猜測是,春天在運行時會增加其類,這就是爲什麼它需要CGLIB庫(它是用於字節碼操作和代碼注入,見here

0

春天肯定會爲你的一些類使用代理機制。

但是,從Spring 3.2版開始,CGLIB sources are repackaged默認添加到spring-core中,因此您不需要手動將CGLIB庫添加到類路徑中。

順便說一句,作爲Michael Isvy的spring blog entrythis issue report狀態,CGLIB項目不再有效。在未來的版本中,Spring將默認使用Javassist。

相關問題