上一篇中在初始化的时候,有读取用户配置的代码,这次我们进来看看。
这里的大部分初始化配置都是基于构造函数的。
MycatServer的构造函数中有个MycatConfig,这个类是保存读取的结果,具体的读取过程是ConfigInitializer来完成的。这里的注释很全,我就不要脸的直接贴了。
public MycatConfig() { //读取schema.xml,rule.xml和server.xml ConfigInitializer confInit = new ConfigInitializer(true); this.system = confInit.getSystem(); this.users = confInit.getUsers(); this.schemas = confInit.getSchemas(); this.dataHosts = confInit.getDataHosts(); this.datanodes = confInit.getDatanodes(); for (PhysicalDBPool dbPool : dataHosts.values()) { dbPool.setSchemas(getDatanodeSchemasOfDataHost(dbPool.getHostName())); } this.firewall = confInit.getFirewall(); this.cluster = confInit.getCluster(); //初始化重加载配置时间 this.reloadTime = TimeUtil.currentTimeMillis(); this.rollbackTime = -1L; this.status = RELOAD; //配置加载锁 this.lock = new ReentrantLock(); }在ConfigInitializer中,初始化了加载rule.xml shcemal.xml的类,之后开始读取server.xml,读取系统配置。
public ConfigInitializer(boolean loadDataHost) { //读取rule.xml和schema.xml SchemaLoader schemaLoader = new XMLSchemaLoader(); //读取server.xml XMLConfigLoader configLoader = new XMLConfigLoader(schemaLoader); schemaLoader = null; //加载配置 this.system = configLoader.getSystemConfig(); this.users = configLoader.getUserConfigs(); this.schemas = configLoader.getSchemaConfigs(); //是否重新加载DataHost和对应的Datanode if (loadDataHost) { this.dataHosts = initDataHosts(configLoader); this.datanodes = initDatanodes(configLoader); } //权限管理 this.firewall = configLoader.getFirewallConfig(); this.cluster = initCobarCluster(configLoader); //不同类型的全局序列处理器的配置加载 if (system.getSequnceHandlerType() == SystemConfig.SEQUENCEHANDLER_MysqLDB) { IncrSequenceMysqLHandler.getInstance().load(); } if (system.getSequnceHandlerType() == SystemConfig.SEQUENCEHANDLER_LOCAL_TIME) { IncrSequenceTimeHandler.getInstance().load(); } if (system.getSequnceHandlerType() == SystemConfig.SEQUENCEHANDLER_ZK_DISTRIBUTED) { DistributedSequenceHandler.getInstance(system).load(); } if (system.getSequnceHandlerType() == SystemConfig.SEQUENCEHANDLER_ZK_GLOBAL_INCREMENT) { IncrSequenceZKHandler.getInstance().load(); } /** * 配置文件初始化, 自检 */ this.selfChecking0(); }在SchemaLoader中会初始化RuleLoader,分别加载不同的xml配置文件。
public XMLSchemaLoader(String schemaFile,String ruleFile) { //先读取rule.xml XMLRuleLoader ruleLoader = new XMLRuleLoader(ruleFile); //将tableRules拿出,用于这里加载Schema做rule有效判断,以及之后的分片路由计算 this.tableRules = ruleLoader.getTableRules(); //释放ruleLoader ruleLoader = null; this.dataHosts = new HashMap<String,DataHostConfig>(); this.datanodes = new HashMap<String,DatanodeConfig>(); this.schemas = new HashMap<String,SchemaConfig>(); //读取加载schema配置 this.load(DEFAULT_DTD,schemaFile == null ? DEFAULT_XML : schemaFile); }这是加载rule.xml
public XMLRuleLoader(String ruleFile) { // this.rules = new HashSet<RuleConfig>(); //rule名 -> rule this.tableRules = new HashMap<String,TableRuleConfig>(); //function名 -> 具体分片算法 this.functions = new HashMap<String,AbstractPartitionAlgorithm>(); load(DEFAULT_DTD,ruleFile == null ? DEFAULT_XML : ruleFile); }每个加载之后,都会对xml进行处理,这里超出我的业余水平多了点,没太看懂,后面的我再详细看看吧,我猜的感觉是分析从xml的根节点开始分析,逐层读出值,加载到mycat的内存中,用java类来保存xml里面的值,方便之后的使用。
private void load(String dtdFile,String xmlFile) { InputStream dtd = null; InputStream xml = null; try { dtd = XMLRuleLoader.class.getResourceAsStream(dtdFile); xml = XMLRuleLoader.class.getResourceAsStream(xmlFile); //读取出语意树 Element root = ConfigUtil.getDocument(dtd,xml) .getDocumentElement(); //加载Function loadFunctions(root); //加载TableRule loadTableRules(root); } catch (ConfigException e) { throw e; } catch (Exception e) { throw new ConfigException(e); } finally { if (dtd != null) { try { dtd.close(); } catch (IOException e) { } } if (xml != null) { try { xml.close(); } catch (IOException e) { } } } }