当前位置: 首页 > news >正文

Seata源码笔记(二)

Seata源码笔记(二)

  • 配置相关的
  • ConfigurationFactory
    • 静态代码块
      • load():融入spring获取value的方式
        • Configuration的get方法拦截后,value取值优先级
          • ObjectHolder
          • PROPERTY_BEAN_MAP
    • getInstance
      • buildConfiguration
    • reload

基于incubartor-seata-2.x

配置相关的

ConfigurationFactory

静态代码块

initOriginConfiguration和maybeNeedOriginFileInstance逻辑较为简单,主要看看load

private static final String REGISTRY_CONF_DEFAULT = "registry";
private static final String ENV_SYSTEM_KEY = "SEATA_ENV";
public static final String ENV_PROPERTY_KEY = "seataEnv";private static final String SYSTEM_PROPERTY_SEATA_CONFIG_NAME = "seata.config.name";private static final String ENV_SEATA_CONFIG_NAME = "SEATA_CONFIG_NAME";public static volatile Configuration CURRENT_FILE_INSTANCE;public static volatile FileConfiguration ORIGIN_FILE_INSTANCE_REGISTRY;public static volatile FileConfiguration ORIGIN_FILE_INSTANCE = null;static {// 负责初始化ORIGIN_FILE_INSTANCE_REGISTRY,通过读取registry.conf(<configName>-<envName>.conf)initOriginConfiguration();// 初始化CURRENT_FILE_INSTANCE(判断是否有extConfiguration,没有就用ORIGIN_FILE_INSTANCE_REGISTRY,本来FileConfiguration就是Configuration的实现)// ext默认有个SpringBootConfigurationProvider实现,返回一个代理对象(seata-spring-autoconfigure-core里)load();// 如果CURRENT_FILE_INSTANCE是.conf的(也就是load用的还是registry.conf)// 那原配置文件ORIGIN_FILE_INSTANCE就用的registry.conf里的config.file.name(test中给的file.conf)maybeNeedOriginFileInstance();
}

load():融入spring获取value的方式

对应上述静态代码块里load部分(主要是通过SPI去找ExtConfigurationProvider的实现然后调用provide方法,目前唯一提供的实现SpringBootConfigurationProvider,它是通过动态代理创建一个Configuration的代理对象,来拦截并设置get方法获取的值)

public class SpringBootConfigurationProvider implements ExtConfigurationProvider {private static final Logger LOGGER = LoggerFactory.getLogger(SpringBootConfigurationProvider.class);private static final String INTERCEPT_METHOD_PREFIX = "get";private static final Map<String, Object> PROPERTY_BEAN_INSTANCE_MAP = new ConcurrentHashMap<>(64);@Overridepublic Configuration provide(Configuration originalConfiguration) {return (Configuration)Enhancer.create(originalConfiguration.getClass(),(MethodInterceptor)(proxy, method, args, methodProxy) -> {if (method.getName().startsWith(INTERCEPT_METHOD_PREFIX) && args.length > 0) {Object result;String rawDataId = (String)args[0];Class<?> dataType = ReflectionUtil.getWrappedClass(method.getReturnType());// 1. Get config value from the system propertyresult = originalConfiguration.getConfigFromSys(rawDataId);if (result == null) {String dataId = convertDataId(rawDataId);// 2. Get config value from the springboot environmentresult = getConfigFromEnvironment(dataId, dataType);if (result != null) {return result;}// 3. Get config defaultValue from the argumentsif (args.length > 1) {result = args[1];if (result != null) {// See Configuration#getConfig(String dataId, long timeoutMills)if (dataType.isAssignableFrom(result.getClass())) {return result;} else {result = null;}}}// 4. Get config defaultValue from the property objecttry {result = getDefaultValueFromPropertyObject(dataId);} catch (Throwable t) {LOGGER.error("Get config '{}' default value from the property object failed:", dataId, t);}}if (result != null) {if (dataType.isAssignableFrom(result.getClass())) {return result;}// Convert typereturn this.convertType(result, dataType);}}return method.invoke(originalConfiguration, args);});}...
}
Configuration的get方法拦截后,value取值优先级

result,也就是get方法的结果读取优先级:

环境变量(步骤1里getenv和getProperty)
ApplicationContext(步骤2里的ObjectHolder,很贴心的做了各种变换去找,下面会去看ObjectHolder怎么来的)
Configuration.getConfig(String dataId, String defaultValue…)(步骤3取默认值)
从PROPERTY_BEAN_MAP获取(步骤4,下面会去看PROPERTY_BEAN_MAP怎么来的)

ObjectHolder

seata-spring-autoconfigure-core的spring.factories配了个自动配置项SeataCoreAutoConfiguration
在这里插入图片描述在这里插入图片描述在这里插入图片描述

PROPERTY_BEAN_MAP

同上,seata-spring-autoconfigure-core的spring.factories配了个自动配置项SeataCoreEnvironmentPostProcessor,并且client和server包里也配置了SeataClientEnvironmentPostProcessor和SeataServerEnvironmentPostProcessor
在这里插入图片描述

getInstance

buildConfiguration

reload

工作去了,晚点更

http://www.lryc.cn/news/483427.html

相关文章:

  • 【Java SE】接口类型
  • [代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
  • redis:RDB和AOF机制
  • 券商隔夜单自动下单交易接口
  • 生成任意3D和4D场景!GenXD:通用3D-4D联合生成框架 | 新加坡国立微软
  • 通过命令学习k8s
  • 【redis】—— 初识redis(redis基本特征、应用场景、以及重大版本说明)
  • 服务器显卡和桌面pc显卡有什么不同
  • Chrome使用IE内核
  • 类和对象(C++)——默认成员函数,构造函数,析构函数
  • 深入理解 Vue v-model 原理与应用
  • 内网域环境、工作组、局域网等探针方案
  • uniapp—android原生插件开发(3Android真机调试)
  • goframe开发一个企业网站 统一返回响应码 18
  • 基于STM32的智能门禁系统设计
  • Python学习从0到1 day28 Python 高阶技巧 ⑧ 递归
  • 知识见闻 - 苹果手机拨号键长按
  • 在 KubeVirt 中使用 GPU Operator
  • 安慰剂检验Stata代码(全套代码、示例数据及参考文献)
  • DAY6 线程
  • 基于STM32的智能门锁系统设计思路:蓝牙、RFID等技术
  • AndroidStudio-广播
  • 基于表格滚动截屏(表格全部展开,没有滚动条)
  • 洛谷P1255
  • vue3设置第三方组件 样式::v-deep
  • JAVA学习日记(十四)集合进阶
  • mysql全量与增量备份
  • “非法”操控lambda(python)
  • UDP协议和TCP协议之间有什么具体区别?
  • 论文5—《基于改进YOLOv5s的轻量化金银花识别方法》文献阅读分析报告