我想使用最新版本的spring-batch-admin-manager(v.1.3.0)将现有的spring批处理作业迁移到Spring-Boot webapp。
@Configuration
@EnableAutoConfiguration(exclude = { BatchAutoConfiguration.class, DataSourceAutoConfiguration.class, WebMvcAutoConfiguration.class })
@Import(MainConfiguration.class) @EnableTransactionManagement
public class BatchAdmin extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(BatchAdmin.class, args);
}
// ...
}
@Configuration @ComponentScan("com.company.package*")
@Import({ ServletConfiguration.class, WebappConfiguration.class })
public class MainConfiguration {}
@Configuration
@ImportResource("classpath:/org/springframework/batch/admin/web/resources/servlet-config.xml")
public class ServletConfiguration {}
@Configuration
@ImportResource({ "classpath:/org/springframework/batch/admin/web/resources/webapp-config.xml"
,"classpath:persistence-context.xml" })
public class WebappConfiguration {}
在我的persistence.xml
我配置了两个数据源,使用了两个PlatformTransactionManager
个实例。
显然,spring-boot默认情况下无法处理这种情况。
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: transactionManager,osm.transactionManager
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:313)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:337)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:252)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
//...
任何想法如何覆盖spring-boot默认值,以便我可以一起使用两个数据源?
编辑:奇怪的是,尽管定义了两个不同的JpaTransactionManager
bean,但事务方面支持似乎没有bean的名称
<bean id="osm.transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="osm.entityManagerFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="osm.transactionManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="osmServiceOperation"
expression="execution(* com.company.osm.service.spec..*Service.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="osmServiceOperation" />
</aop:config>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
从beanFactory
的getBean方法抛出错误:
protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
// ...
else if (this.transactionManagerBeanName != null) { <-- Should go here!
return this.beanFactory.getBean(this.transactionManagerBeanName, PlatformTransactionManager.class);
}
else {
return this.beanFactory.getBean(PlatformTransactionManager.class); <-- Goes here!
}
}
答案 0 :(得分:0)
您必须手动配置数据源:
@Bean
public DataSource dataSource1() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
@Bean
public DataSource dataSource2() {
...
return dataSource;
}
这样,由spring自动配置的数据源将不再可用。
如果您自动装配数据源,请小心。您必须使用限定符来指定应使用哪一个。