#鏈接數據庫地址,該地址可動態添加,「link.」以後,「.jdbc」以前的名稱爲數據庫鏈接池的名稱, #其他鏈接池屬性若是不寫,將自動繼承Hummer的數據庫鏈接池配置 link.eagle2.business.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.155:1521:orcl link.eagle2.business.jdbc.user=eagle2 link.eagle2.business.jdbc.password=eagle2_password link.eagle2.interface.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.155:1521:interface link.eagle2.interface.jdbc.user=interface link.eagle2.interface.jdbc.password=interface22 link.eagle2.ods.jdbc.jdbcUrl=jdbc:oracle:thin:@192.168.0.10:1521:sifen link.eagle2.ods.jdbc.user=honghe link.eagle2.ods.jdbc.password=honghe_pwd
import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.ChildBeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.io.support.ResourcePropertySource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DynamicDataSourceC3p0 implements ApplicationContextAware,ApplicationListener { private ApplicationContext app; @Override public void setApplicationContext(ApplicationContext app) throws BeansException { this.app = app; } public void onApplicationEvent(ApplicationEvent event) { //若是是容器刷新事件 if(event instanceof ContextRefreshedEvent ){//若是是容器關閉事件 try { regDynamicBean(); } catch (IOException e) { e.printStackTrace(); } //System.out.println(event.getClass().getSimpleName()+" 事件已發生!"); } } private void regDynamicBean() throws IOException{ // 解析屬性文件,獲得數據源Map Map<String, DataSourceInfo> mapCustom= parsePropertiesFile("hummer.properties"); // 把數據源bean註冊到容器中 addSourceBeanToApp(mapCustom); } /** * 功能說明:根據DataSource建立bean並註冊到容器中 * @param acf * @param mapCustom */ private void addSourceBeanToApp(Map<String, DataSourceInfo> mapCustom) { DefaultListableBeanFactory acf = (DefaultListableBeanFactory) app.getAutowireCapableBeanFactory(); BeanDefinition beanDefinition; Iterator<String> iter = mapCustom.keySet().iterator(); while(iter.hasNext()){ String beanKey = iter.next(); // 獲得Bean定義,並添加到容器中 beanDefinition = new ChildBeanDefinition("dataSource"); // 注意:必須先註冊到容器中,再獲得Bean進行修改,不然數據源屬性不能有效修改 acf.registerBeanDefinition(beanKey, beanDefinition); // 再獲得數據源Bean定義,並修改鏈接相關的屬性 ComboPooledDataSource cpds = (ComboPooledDataSource)app.getBean( beanKey); cpds.setJdbcUrl(mapCustom.get(beanKey).connUrl); cpds.setUser(mapCustom.get(beanKey).userName); cpds.setPassword(mapCustom.get(beanKey).password); } } /** * 功能說明:解析屬性文件,獲得數據源Map * @return * @throws IOException */ private Map<String, DataSourceInfo> parsePropertiesFile(String fileName) throws IOException { // 屬性文件 ResourcePropertySource props = new ResourcePropertySource(fileName); Matcher matcher; Pattern pattern = Pattern.compile("^link\\.(eagle2\\.\\w+)\\.jdbc\\. (jdbcUrl|user|password)$"); Map<String, DataSourceInfo> mapDataSource = new HashMap<String,DataSourceInfo>(); // 根據配置文件解析數據源 for(String keyProp : props.getPropertyNames()) { matcher = pattern.matcher(keyProp); if(matcher.find()){ String dsName = matcher.group(1); String dsPropName = matcher.group(2); DataSourceInfo dsi; if(mapDataSource.containsKey(dsName)){ dsi = mapDataSource.get(dsName); } else{ dsi = new DataSourceInfo(); } // 根據屬性名給數據源屬性賦值 if("jdbcUrl".equals(dsPropName)){ dsi.connUrl = (String)props.getProperty(keyProp); }else if("user".equals(dsPropName)){ dsi.userName = (String)props.getProperty(keyProp); }else if("password".equals(dsPropName)){ dsi.password = (String)props.getProperty(keyProp); } mapDataSource.put(dsName, dsi); } } return mapDataSource; } private class DataSourceInfo{ public String connUrl; public String userName; public String password; public String toString(){ return "(JcbcUrl:"+connUrl+", user:"+userName+", password:"+password+")"; } } }
acf.registerBeanDefinition不用判斷容器中是否已經有相應名字的bean,spring會在該名稱的bean存在時覆蓋,java
不存在時添加。spring