springBoot 数据库读写分离
数据库的读写分离,首先要把spring 中的自动加载的类排除掉,因为我们配置文件配置了多数据源,并且希望自己主导sql语句执行的数据库。
启动类排除自动配置
@SpringBootApplication(
exclude = {DataSourceAutoConfiguration.class})
循环引用问题
┌─────┐
| dataSource defined in class path resource [com/design/readwritedb/config/DataSourceConfig.class]
↑ ↓
| dbMaster defined in class path resource [com/design/readwritedb/config/DataSourceConfig.class]
↑ ↓
| org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker
└─────┘
问题出现原因:
- 自定义的datasource初始化的时候过程触发dataSourceInitializerPostProcessor后置处理器,而该后置处理器会触发DataSourceInitializerInvoker的初始化。
- DataSourceInitializerInvoker的初始化需要构造器注入datasource对象。
- 此处就导致的循环引用的问题
spring的循环引用的解决使用三级缓存,但是针对于循环引用都是构造器的情况就会抛出循环引用报错的问题。缓存存储的是实例化的对象,而若对象实例化的构造器此时就需要注入对象,而循环引用的对象还未初始化完毕,那么就会出现循环引用的问题。
解决方案:
- 在springBoot 启动的时候exclude DataSourceAutoConfiguration
- 用import以全路径的形式注入bean
数据库初始化相关
DataSourceAutoConfiguration 数据库自动加载
- @ConditionalOnClass 注解判断是否需要加载数据库
- @EnableConfigurationProperties 注解用于加载配置文件中
spring.datasource
相关配置,会验证关键配置 - @Import方法借助两个Configuration生成数据库对象
DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
publ