gpt4 book ai didi

java - Spring Java Config 和@EnableTransactionManagement 的问题

转载 作者:行者123 更新时间:2023-11-29 08:48:53 30 4
gpt4 key购买 nike

我正在从用于 Spring 上下文配置的 XML 配置迁移。相反,当我尝试在 Spring 4.0.3.RELEASE Java 配置上使用功能等效的 @EnableTransactionManagement 时,我的 Spring 上下文无法实例化并出现以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext        at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)        at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)        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:319)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:236)        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:134)        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:113)        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.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseMySQLTest.TestConfig': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.intercep...skipping...        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1558)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)        ... 45 moreCaused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor()] threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)        ... 62 moreCaused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1553)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:324)        at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionInterceptor()        at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration.transactionAdvisor(ProxyTransactionManagementConfiguration.java:45)        at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.CGLIB$transactionAdvisor$0()        at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634$$FastClassBySpringCGLIB$$cc829ae.invoke()        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)        at org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$83a12634.transactionAdvisor()        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.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)        ... 63 moreCaused by: java.lang.IllegalArgumentException: Property 'transactionManager' is required        at org.springframework.transaction.interceptor.TransactionAspectSupport.afterPropertiesSet(TransactionAspectSupport.java:195)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)        ... 82 more

这恰好在单元测试中获得,但当它在这里工作时,我可以在生产代码中使用它。

这是我的单元测试基类,其中发生了 Spring 连接:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class})public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {    @Configuration    @Import(DaoConfig.class)    @PropertySource("classpath:/jdbc.properties")    @EnableTransactionManagement    public static class TestConfig {        @Bean        public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {            return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));        }    }}

这是一个使用这个基类和配置的子类:

public class UserDaoImplTest extends BaseMySQLTest {    @Autowired    private UserDao userDao;    @Test    public void testById() throws Exception {        jdbcTemplate.execute("insert into users (email) values ('bob@example.com')");        ...    }}

可以看到,我的 Spring TestConfig 定义了一个事务管理器 bean,根据 Javadoc

http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html

意味着我不必为 bean 命名(尽管我已经命名它是为了让它工作)。事实上,面对没有明确命名为“transactionManager”的 bean,Spring 上下文的行为就像是使用 XML 配置配置的。

我的 Java Config 缺少什么,以至于 Spring 上下文无法在实例化时使用此事务管理器 bean 来满足其要求?

感谢您提供任何有用的意见。

编辑:

(我不确定这个编辑应该去哪里,所以我在这里试试。ae6rt)

这是新的测试类,它会导致与原始工作相同的错误:

@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {BaseMySQLTest.TestConfig.class})public class BaseMySQLTest extends AbstractTransactionalJUnit4SpringContextTests {    protected int lastInsertId() {        return jdbcTemplate.queryForInt("select LAST_INSERT_ID()");    }    @Autowired    private UserDao userDao;    @Test    public void testById() throws Exception {        jdbcTemplate.execute("insert into mgdb.users (email) values ('bob@example.com')");        int userId = lastInsertId();        Optional xoomUserOptional = userDao.byId(userId);        assertThat(xoomUserOptional.isPresent(), equalTo(true));        XoomUser user = xoomUserOptional.get();        assertThat(user.getEmailAddress(), equalTo("bob@example.com"));    }    @Configuration    @Import(DaoConfig.class)    @PropertySource("classpath:/jdbc.properties")    @EnableTransactionManagement    public static class TestConfig {        @Bean        public PlatformTransactionManager providesTransactionManager(ListableBeanFactory beanFactory) {            return new DataSourceTransactionManager(beanFactory.getBean(DataSource.class));        }    }}

我实际上并不需要这里的属性配置

@ContextConfiguration(类={BaseMySQLTest.TestConfig.class})

所以我删除了它。希望这符合本轮的精神。

最佳答案

看起来唯一的变化应该是将您的事务管理器 bean 名称命名为“transactionManager”:

public static class TestConfig {
@Autowired
private DataSource datasource;

@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(datasource);
}
}

编辑:

你能试试这些额外的东西吗:

.1。从这里删除 PropertyPlaceHolderConfigurer.. @ContextConfiguration(classes = {PropertyPlaceholderConfigurer.class, BaseMySQLTest.TestConfig.class}),这不是 PropertyPlaceholderConfigurer 的使用方式,您必须这样做它是这样的:

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer placeholderConfigurer = new PropertySourcesPlaceholderConfigurer();
ClassPathResource resource = new ClassPathResource("/META-INF/spring/database.properties");
placeholderConfigurer.setLocation(resource);
return placeholderConfigurer;
}

此外,仅用于测试,您能否将实际测试也移至基类,看看这些配置中的一个是否适合您。我在我自己的机器上测试过,它似乎可以很好地与 Spring 4.0.2+ 一起工作。

关于java - Spring Java Config 和@EnableTransactionManagement 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23711363/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com