在搭建Spring Boot 框架时,遇到一个问题,系统包含多数据源,为了扩展
方便,每个数据源单独配置
@Order(1)
@MapperScan(basePackages = "com.zyxx.devplatform.test.dao.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDBConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.primary")
......
//事务管理器
@Bean(name ="primaryTransactionManager")
public DataSourceTransactionManager primaryTransactionManager() {
return new DataSourceTransactionManager(primaryDataSource());
}
......
}
打算使用AOP来管理事务
@Aspect
@Configuration
public class TransactionAspect {
//数据源 primary 切点
private static final String PRIMARY_AOP_POINTCUT_EXPRESSION = "execution(public * com.zyxx.devplatform.test.service.primary..*.*(..))";
//数据源 secondary 切点
private static final String SECONDARY_AOP_POINTCUT_EXPRESSION = "execution(public * com.zyxx.devplatform.test.service.secondary..*.*(..))";
@Resource ApplicationContext applicationContext;
@Resource(name="primaryTransactionManager")
private PlatformTransactionManager primaryTransactionManager;
@Resource (name="secondaryTransactionManager")
private PlatformTransactionManager secondaryTransactionManager;
// public TransactionAspect(PlatformTransactionManager primaryTransactionManager, PlatformTransactionManager secondaryTransactionManager) {
// this.primaryTransactionManager = primaryTransactionManager;
// this.secondaryTransactionManager = secondaryTransactionManager;
// }
@Bean
public TransactionInterceptor txPrimaryAdvice() {
//PlatformTransactionManager o = (PlatformTransactionManager)applicationContext.getBean("primaryTransactionManager");
return new TransactionInterceptor(primaryTransactionManager, createAdviceRule());
}
@Bean
public TransactionInterceptor txSecondaryAdvice() {
//PlatformTransactionManager o = (PlatformTransactionManager)applicationContext.getBean("secondaryTransactionManager");
return new TransactionInterceptor(secondaryTransactionManager, createAdviceRule());
}
@Bean
public Advisor txPrimaryAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(PRIMARY_AOP_POINTCUT_EXPRESSION);
TransactionInterceptor txAdvice = txPrimaryAdvice();
return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
@Bean
public Advisor txSecondaryAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(SECONDARY_AOP_POINTCUT_EXPRESSION);
TransactionInterceptor txAdvice = txSecondaryAdvice();
return new DefaultPointcutAdvisor(pointcut, txAdvice);
}
@Bean
NameMatchTransactionAttributeSource createAdviceRule(){
// 事务管理规则,声明具备事务管理的方法名
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
......
return source;
}
}
然鹅,使用时,报异常
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2: primaryTransactionManager,secondaryTransactionManager
调试后发现,secondaryTransactionManager在注入txSecondaryAdvice时
为null,primaryTransactionManager则大部分时间并无问题,偶尔似乎也为空。采用构造函数注入方式(参看注释掉的构造函数),或者使用applicationContext来获取Bean(参看txSecondaryAdvice),则没有问题,可以正常使用,是否有人知道这是为什么吗?