Seata Configuration解析

seata-core Configuration

Configuration配置接口类

此接口类作用:获取配置文件,注册属性监听事件;

通过spi机制实现第三方配置中心,或本地File文件实现seata配置。

拿Zookeeper举例

  • ZookeeperConfiguration配置类详解:

spi机制创建ZookeeperConfigurationProvider类,类中provide() 实例化 ZookeeperConfiguration类

public interface Configuration { //省略了部分接口
/** * Gets config. * * @param dataId the data id * @param defaultValue the default value * @param timeoutMills the timeout mills * @return the config */ String getConfig(String dataId, String defaultValue, long timeoutMills);
String getConfig(String dataId);
boolean putConfig(String dataId, String content, long timeoutMills);
String getLatestConfig(String dataId, String defaultValue, long timeoutMills);
boolean removeConfig(String dataId, long timeoutMills);
/** * Add config listener. * * @param dataId the data id * @param listener the listener */ void addConfigListener(String dataId, ConfigurationChangeListener listener);
void removeConfigListener(String dataId, ConfigurationChangeListener listener);
Set<ConfigurationChangeListener> getConfigListeners(String dataId);}
AbstractConfiguration 实现接口类 Configuration//zk配置类public class ZookeeperConfiguration extends AbstractConfiguration {
//1. 先执行静态成员变量 见下图 ConfigurationFactory 和 FileConfiguration 类 Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE; ...
//2. 无参构造函数创建zkClient实例 public ZookeeperConfiguration() { if (zkClient == null) { synchronized (ZookeeperConfiguration.class) { if (zkClient == null) { //省略部分代码
//获取配置文件中属性,传入zkClient String serverAddr = FILE_CONFIG.getConfig(FILE_CONFIG_KEY_PREFIX + SERVER_ADDR_KEY); zkClient = new ZkClient(serverAddr, sessionTimeout, connectTimeout, zkSerializer); } } if (!zkClient.exists(ROOT_PATH)) { zkClient.createPersistent(ROOT_PATH, true); } } }
  • ConfigurationFactory类:
public final class ConfigurationFactory {
public static Configuration CURRENT_FILE_INSTANCE;
static { load(); }
private static void load() { //省略部分获取系统参数代码 String seataConfigName = "registry"; //创建FileConfiguration对象 Configuration configuration = new FileConfiguration(seataConfigName, false); CURRENT_FILE_INSTANCE = configuration; }
  • FileConfiguration类: 
public class FileConfiguration extends AbstractConfiguration{ private FileConfig fileConfig; public FileConfiguration(String name, boolean allowDynamicRefresh) { //getConfigFile方法获取classpath根目录资源文件, 此处name用默认配置,创建registry.conf文件 File file = getConfigFile(name); if (file == null) { targetFilePath = null; } else { targetFilePath = file.getPath(); //默认创建SimpleFileConfig对象,类中有参构造函数创建配置管理库typesafe.config fileConfig = FileConfigFactory.load(file, name); } /** * For seata-server side the conf file should always exists. * For application(or client) side,conf file may not exists when using seata-spring-boot-starter */ if (targetFilePath == null) { fileConfig = FileConfigFactory.load(); this.allowDynamicRefresh = false; } else { targetFileLastModified = new File(targetFilePath).lastModified(); this.allowDynamicRefresh = allowDynamicRefresh; } }}

配置监听类ConfigurationChangeListener解析

作用:针对需要监听的配置属性,加入监听事件,属性修改后收到变更事件;

           如后文GlobalTransactionalInterceptor 重写 onChangeEvent 处理相关逻辑

  • Zookeeper怎么写入监听?

ZKListener 实现 zk数据监听接口,需要监听的子节点写入zk监听器,如果有变更则回调方法通知

public class ZookeeperConfiguration extends AbstractConfiguration {
private ConcurrentMap<String, ConcurrentMap<ConfigurationChangeListener, ZKListener>> configListenersMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
//相关属性加入监听 @Override public void addConfigListener(String dataId, ConfigurationChangeListener listener) { if (StringUtils.isBlank(dataId) || listener == null) { return; } String path = ROOT_PATH + ZK_PATH_SPLIT_CHAR + dataId; if (zkClient.exists(path)) { ZKListener zkListener = new ZKListener(path, listener); configListenersMap.computeIfAbsent(dataId, key -> new ConcurrentHashMap<>()) .put(listener, zkListener); zkClient.subscribeDataChanges(path, zkListener); } } @Override public void removeConfigListener(String dataId, ConfigurationChangeListener listener) { //...省略部分代码
//移除监听事件 zkClient.unsubscribeDataChanges(path, zkListener); }
public static class ZKListener implements IZkDataListener {
private String path; private ConfigurationChangeListener listener;
public ZKListener(String path, ConfigurationChangeListener listener) { this.path = path; this.listener = listener; }
@Override public void handleDataChange(String s, Object o) throws Exception { //创建监听的属性对象,作为参数传入自定义的监听类中 ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(s).setNewValue(o.toString()) .setChangeType(ConfigurationChangeType.MODIFY); //处理定义的监听事件 listener.onProcessEvent(event); }
@Override public void handleDataDeleted(String s) throws Exception { ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(s).setChangeType( ConfigurationChangeType.DELETE); listener.onProcessEvent(event); } }}

总结

seata通过定义Configuration接口,第三方配置中心如zk, nacos需要集成,则实现其接口、重写方法完成配置的读取。

声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/221963.html

联系我们
联系我们
分享本页
返回顶部