spring 动态创建bean

来源:互联网 发布:数据分析专业 上海财经 编辑:程序博客网 时间:2024/06/11 16:21

spring中可用java代码动态创建bean,具体应用场景:可以用于spring项目启动时加载数据源DataSource和jdbcTemplate:

spring具体的创建的代码如下

1、BeanUtil 的代码如下

import java.util.Iterator;import java.util.List;import java.util.Map;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.context.ApplicationContext;/** * 管理bean类 */public class BeanUtil {    // Spring Bean 工厂    public static DefaultListableBeanFactory beanFactory;    //注意在spring初始化刷新后要调用这个init方法来获得新的beanFactory对象    public static void init(ApplicationContext applicationContext) {        beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();    }    /**     * 动态增加bean     *      * @param className     * @param beanKey     * @param propertyMap     * @param referenceMap     * @return     */    public static boolean addBean(            String className, String beanKey, Map<String, Object> propertyMap,            Map<String, String> referenceMap, List<Object> propertyConstrList,            List<String> referenceConstrList, String destroyMethod) {        // 判断Spring容器中是否存在该Bean        if (beanFactory.containsBeanDefinition(className)) {            return true;        }        BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(className);        bdb.getBeanDefinition().setAttribute("id", beanKey);        // 设置bean参数属性        if (propertyMap != null && !propertyMap.isEmpty()) {            Iterator<String> propertyKeys = propertyMap.keySet().iterator();            while (propertyKeys.hasNext()) {                String keyString = propertyKeys.next();                bdb.addPropertyValue(keyString, propertyMap.get(keyString));            }        }        // 设置bean参数引用        if (referenceMap != null && !referenceMap.isEmpty()) {            Iterator<String> referenceKeys = referenceMap.keySet().iterator();            while (referenceKeys.hasNext()) {                String keyString = referenceKeys.next();                bdb.addPropertyReference(keyString, referenceMap.get(keyString));            }        }        // 设置bean构造参数属性        if (propertyConstrList != null && !propertyConstrList.isEmpty()) {            for (int i = 0; i < propertyConstrList.size(); i++) {                bdb.addConstructorArgValue(propertyConstrList.get(i));            }        }        // 设置bean构造参数引用        if (referenceConstrList != null && !referenceConstrList.isEmpty()) {            for (int i = 0; i < referenceConstrList.size(); i++) {                bdb.addConstructorArgReference(referenceConstrList.get(i));            }        }        if (destroyMethod != null && !destroyMethod.isEmpty()) {            bdb.setDestroyMethodName(destroyMethod);        }        beanFactory.registerBeanDefinition(beanKey, bdb.getBeanDefinition());        return true;    }    /**     * 获取Bean     *      * @param requiredType     * @return     */    public static <T> T getBean(Class<T> requiredType) {        return beanFactory.getBean(requiredType);    }    /**     * 获取bean     * @param beanName     * @param requiredType     * @return     */    public static <T> T getBean(String beanName,Class<T> requiredType) {        return  beanFactory.getBean(beanName,requiredType);    }}

2、DataSourceUtil 类的代码如下

import java.io.File;import java.io.FileInputStream;import java.io.FilenameFilter;import java.io.InputStreamReader;import java.io.Reader;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Properties;import org.springframework.context.ApplicationContext;import org.springframework.jdbc.core.JdbcTemplate;import com.test.BaseConfigUtil;/** * 加载数据源类,将${catalina.home}/ybg/conf下面的所有数据源文件加入到bean工厂中 */public class DataSourceUtil {    /**     * 初始化     *      * @param applicationContext     */    public static void init(ApplicationContext applicationContext) {            File dataDirectory = new File(System.getProperty("catalina.home") + File.separator + "test" + File.separator + "conf");    // 数据源文件必定要是properties类型。     //过滤的文件名称以db开头,以properties结尾        File[] dataFiles = dataDirectory.listFiles(new FilenameFilter() {            @Override            public boolean accept(File dir, String name) {                String fileName = name.toLowerCase();                if (fileName.endsWith(".properties")) {                    if(fileName.startsWith("db")) {                        return true;                    }                }                return false;            }        });    try (Reader reader = new InputStreamReader(new FileInputStream(dataFiles[i]), "UTF-8")) {                Properties properties = new Properties();                properties.load(reader);//读取数据库的.properties配置文件                if (!properties.isEmpty()) {                    // 建立数据源的bean                    Map<String, Object> propertyMap = new HashMap<String, Object>();                    propertyMap.put("driverClassName",properties.getProperty("sqlDriver"));                    propertyMap.put("url",properties.getProperty("sqlUrl"));                    propertyMap.put("username",properties.getProperty("sqlUsername"));                    propertyMap.put("password", properties.getProperty("sqlPassword"));                    propertyMap.put("initialSize",properties.getProperty("sqlInitialSize"));                    propertyMap.put("maxTotal",properties.getProperty("sqlMaxTotal"));                    propertyMap.put("maxIdle",properties.getProperty("sqlMaxIdle"));                    propertyMap.put("maxWaitMillis",properties.getProperty("sqlMaxWaitMillis"));                    BeanUtil.addBean( "org.apache.commons.dbcp2.BasicDataSource", name + "_dataSource", propertyMap, null, null, null, "close");                    // 建立jdbcTemplate的bean                    List<String> referenceConstrList = new ArrayList<String>();                    referenceConstrList.add(name + "_dataSource");                    BeanUtil.addBean( "org.springframework.jdbc.core.JdbcTemplate", name + "_jdbcTemplate", null, null, null, referenceConstrList, null);                    LogUtil.info("load datasource file {} success!", dataFiles[i].getAbsolutePath());                }            } catch (Exception e) {                LogUtil.error("load datasource file {} fail!", dataFiles[i].getAbsolutePath());            }        }}    /**     * 获取数据源     * @param datasourceFileName 数据源配置文件名     * @return     */    public static JdbcTemplate getJdbcTemplate(String datasourceFileName) {        String id = datasourceFileName + "_jdbcTemplate";        return BeanUtil.getBean(id, JdbcTemplate.class);    }}

动态创建bean的代码位置如下图
动态创建bean的示意图

3、类比如下用xml加载dataSource和jdbcTemplate的方法

    <!-- 数据源配置 -->    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">        <property name="driverClassName" value="${sqlDriver}" />        <property name="url"             value="${sqlUrl}" />        <property name="username"        value="${sqlUsername}" />        <property name="password"        value="${sqlPassword}" />        <property name="initialSize"     value="${sqlInitialSize}"/>          <!-- 连接池启动时创建的连接数 -->        <!-- 连接池最大连接数 -->        <property name="maxIdle"         value="${sqlMaxIdle}"/>              <!-- 连接池最大空闲连接数。推荐与 maxTotal 的值一致。 -->        <!-- 等待获取连接的时间.毫秒 -->    </bean>     <!-- 配置Spring对数据库事务的支持   -->    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" c:dataSource-ref="dataSource"/>    <!-- 开启注解事务的支持 -->    <tx:annotation-driven transaction-manager="txManager"/>    <!-- 配置Template -->    <bean id="Template" class="org.springframework.jdbc.core.JdbcTemplate" c:dataSource-ref="dataSource"/>
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 感冒就清鼻涕怎么办 怀孕感冒流鼻涕打喷嚏怎么办 过敏性鼻炎打喷嚏流鼻涕怎么办 宝宝黄鼻涕鼻塞怎么办 鼻炎总是打喷嚏流鼻涕怎么办 新生儿流黄鼻涕怎么办 感冒鼻塞流鼻涕喷嚏怎么办 宝宝总是打喷嚏流鼻涕怎么办 不停的打喷嚏流鼻涕怎么办 宝宝不停打喷嚏流鼻涕怎么办 孕妇感冒流鼻涕打喷嚏怎么办 孕妇感冒咳嗽流鼻涕怎么办 鼻子痒流鼻涕流眼泪怎么办 天冷鼻子流鼻涕怎么办 感冒流水样鼻涕怎么办 一直有清水鼻涕怎么办 孩子总打喷嚏鼻塞怎么办 4岁儿童流鼻涕怎么办 孕妇清鼻涕不停怎么办 感冒流鼻水怎么办速效办法 一岁宝宝流清涕怎么办 咳嗽喉咙痛有痰怎么办 冻感冒了流鼻涕怎么办 吸烟经常嗓子疼怎么办 擦鼻涕擦破了怎么办 感冒鼻水流不停怎么办 流鼻涕鼻子都擦红了怎么办 鼻子不停的流水怎么办 擦鼻涕耳朵疼怎么办 鼻涕跟水一样怎么办 鼻涕水多打喷嚏怎么办 买来的鼻涕泥是水怎么办? 鼻炎鼻涕跟水怎么办 出门忘记带钥匙怎么办 总留鼻涕水怎么办 流像水一样的鼻涕怎么办 出门忘记带洗面奶怎么办 一侧鼻子流清水怎么办 慢性肠胃炎犯了怎么办 儿子拉肚肚子疼怎么办 皮肤太容易过敏怎么办