看到canal源码的时候发现了好多这样的写法
<bean id="eventParser" class="com.alibaba.otter.canal.parse.inbound.mysql.MysqlEventParser">
<property name="destination" value="${canal.instance.destination}" />
<property name="slaveId" value="${canal.instance.mysql.slaveId:1234}" />
<!-- 心跳配置 -->
<property name="detectingEnable" value="${canal.instance.detecting.enable:false}" />
<property name="detectingSQL" value="${canal.instance.detecting.sql}" />
<property name="detectingIntervalInSeconds" value="${canal.instance.detecting.interval.time:5}" />
<property name="haController">
<bean class="com.alibaba.otter.canal.parse.ha.HeartBeatHAController">
<property name="detectingRetryTimes" value="${canal.instance.detecting.retry.threshold:3}" />
<property name="switchEnable" value="${canal.instance.detecting.heartbeatHaEnable:false}" />
</bean>
</property>
property的属性${canal.instance.mysql.slaveId:1234} 取配置文件key的时候带了:后面跟了一个值 后来才发现这是对spring placeholder 设置默认值的一种扩展。
/**
* 扩展Spring的
* {@linkplain org.springframework.beans.factory.config.PropertyPlaceholderConfigurer}
* ,增加默认值的功能。 例如:${placeholder:defaultValue},假如placeholder的值不存在,则默认取得
* defaultValue。
* @author jianghang 2013-1-24 下午03:37:56
* @version 1.0.0
* */
看一下类图
这里只要实现了InitializingBean的afterPropertiesSet方法 和 ResourceLoaderAware 的setResourceLoader方法将资源的路径解析出来,然后加载资源 。重写了 PropertyPlaceholderConfigurer 的resolvePlaceholder 方法,先解析成DefaultablePlaceholder,然后发现取不到一个属性的时候将默认值赋给该属性,其中默认值是冒号后面的值。DefaultablePlaceholder 是新定义的内部类。
贴出主要实现的代码
@Override
protected String resolvePlaceholder(String placeholder, Properties props, int systemPropertiesMode) {
DefaultablePlaceholder dp = new DefaultablePlaceholder(placeholder);
String value = super.resolvePlaceholder(dp.placeholder, props, systemPropertiesMode);
if (value == null) {
value = dp.defaultValue;
}
return trimToEmpty(value);
}
private static class DefaultablePlaceholder {
private final String defaultValue;
private final String placeholder;
public DefaultablePlaceholder(String placeholder){
int commaIndex = placeholder.indexOf(":");
String defaultValue = null;
if (commaIndex >= 0) {
defaultValue = trimToEmpty(placeholder.substring(commaIndex + 1));
placeholder = trimToEmpty(placeholder.substring(0, commaIndex));
}
this.placeholder = placeholder;
this.defaultValue = defaultValue;
}
}