我想构造一个spring-mybatis-mutiple-xa-datasources-starter,它可以动态地注册外部文件(例如yaml或属性文件)中的数据源,并支持分布式事务(使用Atomikos)。
我从yaml文件中获取了属性(使用snakeyaml):
datasourceList:
- validationQuery: SELECT 1
initialSize: 3
maxActive: 100
maintenanceInterval: 28000
name: primaryDataSource
url: jdbc:mysql://127.0.0.1:3306/prong_m1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B1
username: root
password: 123456
driverClassName: com.mysql.cj.jdbc.Driver
filters: stat
maxWait: 300000
minIdle: 5
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
asyncInit: true
atomikBorrowConnectionTimeout: 60
sqlSessionFactory: primarySqlSessionFactory
sqlSessionTemplate: primarySqlSessionTemplate
mapperScannerConfigurer: primaryScannerConfigurer
basePackage: com.sample3.dao.db1
isPrimary: true
mapperLocation: classpath*:mapper/db1/*.xml
typeAliasesPackage: com.sample3.model.db1
- validationQuery: SELECT 1
initialSize: 3
maxActive: 100
maintenanceInterval: 28000
name: hesDataSource
url: jdbc:mysql://127.0.0.1:3306/prong_m2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B1
username: root
password: 123456
driverClassName: com.mysql.cj.jdbc.Driver
filters: stat
maxWait: 300000
minIdle: 5
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
asyncInit: true
atomikBorrowConnectionTimeout: 60
sqlSessionFactory: hesSqlSessionFactory
sqlSessionTemplate: hesSqlSessionTemplate
mapperScannerConfigurer: hesScannerConfigurer
basePackage: com.sample3.dao.db2
isPrimary: false
mapperLocation: classpath*:mapper/db2/*.xml
typeAliasesPackage: com.sample3.model.db2
- validationQuery: SELECT 1
initialSize: 3
maxActive: 100
maintenanceInterval: 28000
name: seqDataSource
url: jdbc:mysql://127.0.0.1:3306/prong_m3?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B1
username: root
password: 123456
driverClassName: com.mysql.cj.jdbc.Driver
filters: stat
maxWait: 300000
minIdle: 5
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
asyncInit: true
atomikBorrowConnectionTimeout: 60
sqlSessionFactory: seqSqlSessionFactory
sqlSessionTemplate: seqSqlSessionTemplate
mapperScannerConfigurer: seqScannerConfigurer
basePackage: com.sample3.dao.db3
isPrimary: false
mapperLocation: classpath*:mapper/db3/*.xml
typeAliasesPackage: com.sample3.model.db3
mybatis:
atomikos-location: classpath*:mapper/*.xml
type-aliases-package: prong.springbootmybatis.entity
configuration:
map-underscore-to-camel-case: true
我的数据库中有3种模式:
prong_m1(primary) tables: sys_user
prong_m2 tables: sys_role_rel
prong_m3 tables: sys_org
然后,我创建了一个名为SqlSessionBeanDefinitionRegistryPostProcessor的类,以动态注册数据源,sqlSessionFactories,sqlSessionTemplates和mapperScannerConfigurers,该类实现了BeanDefinitionRegistryPostProcessor :
@Configuration
public class SqlSessionBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(SqlSessionBeanDefinitionRegistryPostProcessor.class);
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
logger.info("Invoke Metho postProcessBeanFactory");
Yaml yaml =