Spring Transactional和CGLIB代理

时间:2014-03-12 19:55:25

标签: java spring transactions aop cglib

我正在尝试在Spring 3.0.7容器内的事务中处理我的数据源更新。我的DAO类没有实现接口,而是作为另一个bean @Autowired的{​​{1}}的具体类。这是布局:

@Component

我的应用程序上下文的事务设置如下(这是一个测试单元bean配置,因为我通过junit / Spring测试用例调用MyService / MyDAO):

@Component
public class MyService {

  @Autowired
  MyDAO myDAO;

  public void myService(MyObj obj) {
    myDAO.updateObj(obj)
  }
}

@Component
public class MyDAO {
  // The data source bean is injected through a setter method
  // and used by updateObj()

  @Transactional
  public void updateObj(MyObj obj) {

     // multiple updates hence the need for transaction
  }
}

我正在使用Ant来执行我的构建。但是,似乎我需要包含CGLIB,因为<!-- language: lang-xml --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="mypkg" /> <bean id="updateDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- properties for the data source --> </bean> <tx:annotation-driven transaction-manager="updateTxManager" /> <bean id="updateTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="updateDataSource" ref="updateDataSource"/> </bean> </beans> 没有实现接口,以便Spring创建代理类。

鉴于我正在运行Spring容器版本3.0.7,沿着spring-aop 3.0.7,spring-asm 3.0.0,aopalliance 1.0,我将cglib-nodep 3.0 jar文件添加到我的lib路径中。但是,在执行我的测试用例时,我得到以下异常:

MyDAO

完整堆栈跟踪:

nested exception is java.lang.NoClassDefFoundError: net/sf/cglib/asm/util/TraceClassVisitor
Caused by: java.lang.ClassNotFoundException: net.sf.cglib.asm.util.TraceClassVisitor

问题

您认为问题可能是容器/ lib版本存在冲突吗?我是否需要另一个我缺少的库?

更新

我必须使用java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) 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:211) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 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:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyDAO' defined in file [C:\Users\.....\dao\MyDAO.class]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: net/sf/cglib/asm/util/TraceClassVisitor at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:526) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:84) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1) at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:280) at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:304) ... 24 more Caused by: java.lang.NoClassDefFoundError: net/sf/cglib/asm/util/TraceClassVisitor at net.sf.cglib.core.DebuggingClassWriter.toByteArray(DebuggingClassWriter.java:73) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26) at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:144) at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:116) at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:108) at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:104) at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69) at org.springframework.aop.framework.Cglib2AopProxy.createEnhancer(Cglib2AopProxy.java:228) at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:170) 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:406) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1428) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:518) ... 36 more Caused by: java.lang.ClassNotFoundException: net.sf.cglib.asm.util.TraceClassVisitor at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:247) ... 53 more 创建项目并拉出依赖项以查看它使用的是哪一个。事实证明有效的是Mavoncglib-nodep-2.2.2asm-3.3.1spring-aop-3.0.7spring-asm-3.0.7

1 个答案:

答案 0 :(得分:2)

cglib需要asm,但cglib-nodep对其进行着色,以便它可以正常工作。但是,Spring使用的是cglib2而不是3.将您的版本更新为cglib-nodep 2.2。

另请注意,从Spring Framework 3.2开始,cglibasmspring-core库中以阴影显示,这意味着您根本不必处理此问题。如果您无法排除该依赖性问题,那可能是最简单的举措。