seata学习-数据源代理

发布时间 2023-08-17 17:08:12作者: float123

代理的动机

AT 模式下

  • 执行 undo-log 回滚日志

代理的是 DateSource 这个类

手动代理

即手动注入一个DataSourceProxy,如下

@Bean
public DataSource druidDataSource() {
    return new DruidDataSource()
}


// 这里会返回名字为 "dataSource" 的 Bean, 这里
@Primary
@Bean("dataSource")
public DataSourceProxy dataSource(DataSource druidDataSource) {
    return new DataSourceProxy(druidDataSource);
}

即使在生成这个类的时候,手动返回一个 proxy

自动代理

针对DataSource创建一个代理类,在代理类里面基于DataSource获取DataSourceProxy(如果没有就创建),然后调用DataSourceProxy的相关方法。核心逻辑在SeataAutoDataSourceProxyCreator

public class SeataAutoDataSourceProxyCreator extends AbstractAutoProxyCreator {
    ... 
}

其中 AbstractAutoProxyCreator 来自 spring-aop

其他 : 自动代理是如何调用的呢 ?

本人的项目是 spring cloud 的依赖如下

        <!-- 阿里相关依赖 -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

这里使用的 seata 版本是 1.7 , 之前用 1.6 以及 1.4 有很多 bug , 从官网可以看到 1.7作为一个大版本更新 ,更新了很多bug提升了性能.

回到上面的问题 : 自动代理是如何调用的呢 ?
即是 SeataAutoDataSourceProxyCreator 是如何给调用的呢 ? 在 seata-spring-boot-starter 这里依赖里面有一个 SeataDataSourceAutoConfiguration , 该类将会引入 SeataAutoDataSourceProxyCreator 完成代理 .

@ConditionalOnBean({DataSource.class})
@ConditionalOnExpression("${seata.enabled:true} && ${seata.enableAutoDataSourceProxy:true} && ${seata.enable-auto-data-source-proxy:true}")
@AutoConfigureOrder(2147483647)
@AutoConfigureAfter(
    value = {SeataCoreAutoConfiguration.class},
    name = {"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"}
)
public class SeataDataSourceAutoConfiguration {
    public SeataDataSourceAutoConfiguration() {
    }


    // 这里注入的
    @Bean({"seataAutoDataSourceProxyCreator"})
    @ConditionalOnMissingBean({SeataAutoDataSourceProxyCreator.class})
    public static SeataAutoDataSourceProxyCreator seataAutoDataSourceProxyCreator(SeataProperties seataProperties) {
        return new SeataAutoDataSourceProxyCreator(seataProperties.isUseJdkProxy(), seataProperties.getExcludesForAutoProxying(), seataProperties.getDataSourceProxyMode());
    }
}

参考资料