package message.datasource.configs.parser;
import message.config.SystemConfig;
import message.config.properties.Configuration;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 关系型数据库的数据源配置.
*
* @author sunhao(sunhao.java@gmail.com)
* @version V1.0, 15/6/21 下午5:28
*/
public class RdbmsDataSourceParser extends BaseDataSourceParser implements BeanDefinitionParser {
/**
* 数据源配置的key
*/
private static final String DATASOURCE_CLASS = "datasources.rdbms.dataSourceClass";
private static final String DATASOURCE_PROPERTY_PREFIX = "datasources.rdbms";
private static final String DEFAULT_PROPERTIES_KEY_PREFIX = DATASOURCE_PROPERTY_PREFIX + ".default";
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//bean对象注册机
BeanDefinitionRegistry registry = parserContext.getRegistry();
//注册数据源
registDataSource(element, registry);
return null;
}
/**
* 注册数据源到spring的上下文中
*
* @param element xml的元素
* @param registry spring bean的注册机
*/
private void registDataSource(Element element, BeanDefinitionRegistry registry) {
//数据源名称
String dataSourceName = getDataSourceName(element);
//判断上下文中是否存在这个数据源
boolean isExist = registry.containsBeanDefinition(dataSourceName);
if (isExist)
return;
String dataSourceClassName = configuration.getString(DATASOURCE_CLASS);
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(dataSourceClassName);
Map<String, String> properties = this.getProperties(dataSourceName);
this.setDataSourceProperty(beanDefinitionBuilder, properties);
this.setCustomProperties(beanDefinitionBuilder, dataSourceClassName);
registry.registerBeanDefinition(dataSourceName, beanDefinitionBuilder.getBeanDefinition());
}
private String getDataSourceName(Element element) {
return element.getAttribute(DATASOURCE_ELE_NAME);
}
private Map<String, String> getProperties(String dataSourceName) {
Map<String, String> properties = new HashMap<String, String>();
String currentDatasourcePrefix = DATASOURCE_PROPERTY_PREFIX + "." + dataSourceName;
Set<String> keys = this.configuration.subset(DEFAULT_PROPERTIES_KEY_PREFIX).getKeys();
keys.addAll(this.configuration.subset(currentDatasourcePrefix).getKeys());
for (String key : keys) {
properties.put(key, this.configuration.getString(currentDatasourcePrefix + "." + key,
this.configuration.getString(DEFAULT_PROPERTIES_KEY_PREFIX + "." + key)));
}
return properties;
}
private void setDataSourceProperty(BeanDefinitionBuilder dataSourceBuilder, Map<String, String> properties) {
Iterator<Map.Entry<String, String>> it = properties.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> entry = it.next();
dataSourceBuilder.addPropertyValue(entry.getKey(), entry.getValue());
}
}
private void setCustomProperties(BeanDefinitionBuilder beanDefinitionBuilder, String dataSourceClassName) {
//1.druid
if ("com.alibaba.druid.pool.DruidDataSource".equals(dataSourceClassName)) {
// init method
beanDefinitionBuilder.setInitMethodName("init");
// destroy method
beanDefinitionBuilder.setDestroyMethodName("close");
}
}
}