spring3.1中动态创建和销毁bean

最近由于新项目是多个数据源,而且数据源配置信息在一个主数据库中,所以需要动态的创建datasource这个bean,不多说了,直接上代码.

package com.gtjy.gxpt.dm.support;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;


import com.gtjy.framework.util.PropertiesUtil;
import com.gtjy.framework.util.security.CryptoUtil;
import com.gtjy.framework.util.spring.SpringUtil;
import com.gtjy.gxpt.dm.datasource.model.DataSource;

public class DataSourceManager {

	public static String DATASOURCE_BEAN_PREFIX = "dataSource_";
	
	
	private static String DATASOURCE_BEAN_CLASS = "com.alibaba.druid.pool.DruidDataSource";
	private static String DATASOURCE_INIT_METHODNAME = "init";
	private static String DATASOURCE_DESTROY_METHODNAME = "close";
	private static String DATASOURCE_CONFIG_ITEM_PREFIX = "druid.";

	private static Set<String> datasourceBeanNames = new HashSet<String>();
	protected static final Logger _log= LoggerFactory.getLogger(DataSourceManager.class);
	
	/**
	 * 添加多个数据源到spring容器
	 * 
	 * @throws Exception
	 */
	public static void add2BeanFactory(List<DataSource> datasourceList)
			throws Exception {
		CryptoUtil passwordGenerator = new CryptoUtil();
		ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) SpringUtil
				.getApplicationContext();
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
				.getBeanFactory();
		for (DataSource ds : datasourceList) {
			String beanName = DATASOURCE_BEAN_PREFIX + ds.getDsId();
			if (!beanFactory.containsBean(beanName)) {
				BeanDefinitionBuilder bdb = BeanDefinitionBuilder
						.rootBeanDefinition(DATASOURCE_BEAN_CLASS);
				// bdb.setScope("prototype");
				// bdb.addPropertyValue("driverClass", ds.getDsDrivername());
				bdb.addPropertyValue("url", ds.getDsUrl());
				bdb.addPropertyValue("username", ds.getDsUsername());
				bdb.addPropertyValue("password", passwordGenerator.decryptDES(ds.getDsPassword()));
				bdb = fitDataSourceBean(bdb,PropertiesUtil.getKeyStartWithBy(DATASOURCE_CONFIG_ITEM_PREFIX));
				bdb = fitDruidPropertie(bdb);
				bdb.setInitMethodName(DATASOURCE_INIT_METHODNAME);
				bdb.setDestroyMethodName(DATASOURCE_DESTROY_METHODNAME);
				beanFactory.registerBeanDefinition(beanName, bdb.getBeanDefinition());
				datasourceBeanNames.add(beanName);
				_log.info("将"+ds.getDsUrl()+"数据源交由spring容器托管 成功!用户名为:"+ds.getDsUsername());
			} else {
				_log.debug("将"+ds.getDsUrl()+"数据源交由spring容器托管 失败!用户名为:"+ds.getDsUsername()+" 失败原因:BeanName为【"+beanName+"】的数据源已被创建");
				throw new Exception("BeanName : " + beanName + "已创建");
			}
		}
	}
	/**
	 * 添加单个数据源到spring容器
	 * @param ds
	 * @throws Exception
	 */
	public static void add2BeanFactory(DataSource ds) throws Exception {
		List<DataSource> datasourceList = new ArrayList<DataSource>();
		datasourceList.add(ds);
		add2BeanFactory(datasourceList);
	}

	private static BeanDefinitionBuilder fitDruidPropertie(BeanDefinitionBuilder bdb){
		bdb.addPropertyValue("filters", "stat,slf4j");
		return bdb;
	}

	private static BeanDefinitionBuilder fitDataSourceBean( BeanDefinitionBuilder bdb, Properties properties) {
		Set<Entry<Object, Object>> keys = properties.entrySet();
		Iterator<Entry<Object, Object>> iterator = keys.iterator();
		while (iterator.hasNext()) {
			Entry<Object, Object> prop = iterator.next();
			String key = prop.getKey().toString();
			if (key.startsWith(DATASOURCE_CONFIG_ITEM_PREFIX)) {
				key = key.substring(DATASOURCE_CONFIG_ITEM_PREFIX.length());
			}
			bdb.addPropertyValue(key, prop.getValue().toString());
		}
		return bdb;
	}

	public static javax.sql.DataSource getDataSource(Serializable id) throws NoSuchBeanDefinitionException {
		String beanName = DATASOURCE_BEAN_PREFIX + id;
		if (datasourceBeanNames.contains(beanName)) {
			return (javax.sql.DataSource) SpringUtil.getBean(beanName);
		}
		throw new NoSuchBeanDefinitionException(beanName);
	}

	private static void _destory(String beanName) {
		ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) SpringUtil
				.getApplicationContext();
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext
				.getBeanFactory();
		// beanFactory.destroyBean(beanName, beanFactory.getBean(beanName));
		_log.info("销毁 BeanName为: "+beanName+" 的数据源 成功");
		_log.info("remove before "+ beanFactory.getBeanDefinitionCount());
		beanFactory.destroySingleton(beanName);
		beanFactory.removeBeanDefinition(beanName);
		_log.info("remove after "+ beanFactory.getBeanDefinitionCount());
		
	}

	public static void destory(Serializable id) {
		_destory(DATASOURCE_BEAN_PREFIX + id);
		datasourceBeanNames.remove(DATASOURCE_BEAN_PREFIX + id);
	}

	public static void destory() {
		List<String> delList = new ArrayList<String>();
		for (String beanName : datasourceBeanNames) {
			_destory(beanName);
			delList.add(beanName);
		}
		datasourceBeanNames.removeAll(delList);
	}

}

你可能感兴趣的:(java,spring)