mybatis

您所在的位置:网站首页 springboot整合mybatis-plus mybatis

mybatis

#mybatis| 来源: 网络整理| 查看: 265

文章已收录到我的Github精选,欢迎Star:https://github.com/yehongzhi/learningSummary

写在前面

上一篇文章大致介绍了dynamic-datasource的功能,用起来的确很方便,只需要一个@DS注解,加上一些简单的配置即可完成多数据源的切换。究竟是怎么做到的呢,底层是怎么实现呢?带着这个疑问,一起研究了一下源码。

由于框架本身功能点比较多,有很多小功能比如支持spel、正则表达式匹配,动态增删数据源这种功能的源码就不去细讲了。我们只关心核心的功能,就是多数据源的切换。

源码解析

首先我们都记得,一开始需要引入spring-boot-starter:

    com.baomidou    dynamic-datasource-spring-boot-starter    3.3.0

一般starter自动配置,都是从 META-INF/spring.factories文件中指定自动配置类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration

接着打开这个类:

/** * 动态数据源核心自动配置类 * * @author TaoYu Kanyuxia * @see DynamicDataSourceProvider * @see DynamicDataSourceStrategy * @see DynamicRoutingDataSource * @since 1.0.0 */@Slf4j@Configuration@AllArgsConstructor//以spring.datasource.dynamic为前缀读取配置@EnableConfigurationProperties(DynamicDataSourceProperties.class)//在SpringBoot注入DataSourceAutoConfiguration的bean自动配置之前,先加载注入当前这个类的bean到容器中@AutoConfigureBefore(DataSourceAutoConfiguration.class)//引入了Druid的autoConfig和各种数据源连接池的Creator@Import(value = {DruidDynamicDataSourceConfiguration.class, DynamicDataSourceCreatorAutoConfiguration.class})//条件加载,当前缀是"spring.datasource.dynamic"配置的时候启用这个autoConfig@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)public class DynamicDataSourceAutoConfiguration {     private final DynamicDataSourceProperties properties;    //读取多数据源配置,注入到spring容器中    @Bean    @ConditionalOnMissingBean    public DynamicDataSourceProvider dynamicDataSourceProvider() {        Map datasourceMap = properties.getDatasource();        return new YmlDynamicDataSourceProvider(datasourceMap);    }    //注册自己的动态多数据源DataSource    @Bean    @ConditionalOnMissingBean    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();        dataSource.setPrimary(properties.getPrimary());        dataSource.setStrict(properties.getStrict());        dataSource.setStrategy(properties.getStrategy());        dataSource.setProvider(dynamicDataSourceProvider);        dataSource.setP6spy(properties.getP6spy());        dataSource.setSeata(properties.getSeata());        return dataSource;    }    //AOP切面,对DS注解过的方法进行增强,达到切换数据源的目的    @Role(value = BeanDefinition.ROLE_INFRASTRUCTURE)    @Bean    @ConditionalOnMissingBean    public DynamicDataSourceAnnotationAdvisor dynamicDatasourceAnnotationAdvisor(DsProcessor dsProcessor) {        DynamicDataSourceAnnotationInterceptor interceptor = new DynamicDataSourceAnnotationInterceptor(properties.isAllowedPublicOnly(), dsProcessor);        DynamicDataSourceAnnotationAdvisor advisor = new DynamicDataSourceAnnotationAdvisor(interceptor);        advisor.setOrder(properties.getOrder());        return advisor;    }    //关于分布式事务加强    @Role(value = BeanDefinition.ROLE_INFRASTRUCTURE)    @ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "seata", havingValue = "false", matchIfMissing = true)    @Bean    public Advisor dynamicTransactionAdvisor() {        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();        pointcut.setExpression("@annotation(com.baomidou.dynamic.datasource.annotation.DSTransactional)");        return new DefaultPointcutAdvisor(pointcut, new DynamicTransactionAdvisor());    }    //动态参数解析器链    @Bean    @ConditionalOnMissingBean    public DsProcessor dsProcessor() {        DsHeaderProcessor headerProcessor = new DsHeaderProcessor();        DsSessionProcessor sessionProcessor = new DsSessionProcessor();        DsSpelExpressionProcessor spelExpressionProcessor = new DsSpelExpressionProcessor();        headerProcessor.setNextProcessor(sessionProcessor);        sessionProcessor.setNextProcessor(spelExpressionProcessor);        return headerProcessor;    }}

我们可以发现,在使用的时候配置的前缀为spring.datasource.dynamic的配置都会被读取到DynamicDataSourceProperties类,作为一个Bean注入到Spring容器。其实这种读取配置文件信息的方式在日常开发中也是很常见的。

@Slf4j@Getter@Setter@ConfigurationProperties(prefix = DynamicDataSourceProperties.PREFIX)public class DynamicDataSourceProperties {    public static final String PREFIX = "spring.datasource.dynamic";    public static final String HEALTH = PREFIX + ".health";    /**     * 必须设置默认的库,默认master     */    private String primary = "master";    /**     * 是否启用严格模式,默认不启动. 严格模式下未匹配到数据源直接报错, 非严格模式下则使用默认数据源primary所设置的数据源     */    private Boolean strict = false;    /**     * 是否使用p6spy输出,默认不输出     */    private Boolean p6spy = false;    /**     * 是否使用开启seata,默认不开启     */    private Boolean seata = false;    /**     * seata使用模式,默认AT     */    private SeataMode seataMode = SeataMode.AT;    /**     * 是否使用 spring actuator 监控检查,默认不检查     */    private boolean health = false;    /**     * 每一个数据源     */    private Map datasource = new LinkedHashMap();    /**     * 多数据源选择算法clazz,默认负载均衡算法     */    private Class


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3