博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟Spring中applicationContext.xml配置文件初始化bean的过程
阅读量:6862 次
发布时间:2019-06-26

本文共 5059 字,大约阅读时间需要 16 分钟。

package com.xiaohao.action;import java.io.File;import java.lang.reflect.Method;import java.util.Collections;import java.util.HashMap;import java.util.Map;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;/** * 需要导入dom4j的jar包  * @author 小浩 * @创建日期 2015-4-4 */public class BeanFactory {			/**     * 保存容器中所有单例模式的bean实例,这里的hashMap是线程安全的     *     */		private static Map
beanPool=Collections.synchronizedMap(new HashMap
()); //保存文件对应的Document对象 private Document document; //保存配置文件里的根元素 private Element root; /** * 构造方法,指定需要读取的文件的路径 * @param filePath * @throws Exception */ public BeanFactory(String filePath) throws Exception{ //使用dom4j读取xml配置文件 SAXReader reader=new SAXReader(); document=reader.read(new File(filePath)); root=document.getRootElement(); //进行容器的初始化 initPool(); //初始化单例bean的属性 initProp(); } /** * 获取指定的bean * @param name * @return * @throws Exception */ public static Object getBean(String name) throws Exception { Object target = beanPool.get(name); //对于单例bean,容器已经初始化了所有的Bean实例 if(target.getClass() != String.class){ return target; }else{ String clazz = (String)target; //对于非单例的并未注入属性值 return Class.forName(clazz).newInstance(); } } /** * 初始化容器中的所有单例bean * */ private void initPool() throws Exception{ //遍历配置文件中的每个
元素 for(Object obj:root.elements()){ Element beanElement = (Element)obj; //获取Bean元素中的id属性 String beanId = beanElement.attributeValue("id"); //获取bean元素中的class属性 String beanClazz = beanElement.attributeValue("class"); //获取bean元素中的scope属性 String beanScope = beanElement.attributeValue("scope"); //如果scope属性不存在或为singleton if(beanScope == null|| beanScope.equals("singleton")){ //以默认构造方法创建bean实例,并将其放入beanPool中 beanPool.put(beanId, Class.forName(beanClazz).newInstance()); //利用反射的技术 }else{ //对于非单例的,存放Bean实现类的类名 beanPool.put(beanId, beanClazz); } } }/** * 初始化容器中的单例bean * */private void initProp() throws Exception{ //遍历配置文件中的所有bean元素,即根节点的子节点 for(Object object:root.elements()){ Element beanElement = (Element)object; //获取Bean元素中的id属性 String beanId = beanElement.attributeValue("id"); //获取bean元素中的scope属性 String beanScope = beanElement.attributeValue("scope"); //如果scope属性不存在或为singleton if(beanScope == null|| beanScope.equals("singleton")){ //取出beanPool的指定bean实例 Object bean = beanPool.get(beanId); //遍历bean属性下的所有property属性 for(Object prop: beanElement.elements()){ Element probElement = (Element)prop; //获取property的name属性 String propName = probElement.attributeValue("name"); //获取property的value属性 String propValue = probElement.attributeValue("value"); //获取property的ref属性 String propRef = probElement.attributeValue("ref"); //将属性名的首字母大写 String propNameCamelize = propName.substring(0,1).toUpperCase() +propName.substring(1, propName.length()); //如果value值存在 if(propValue != null&&propValue.length()> 0){ //获取设置注入所需要的setter方法 java.lang.reflect.Method setter = bean.getClass().getMethod("set"+propNameCamelize, String.class); //执行setter注入 setter.invoke(bean, propValue); } if(propRef != null&&propRef.length()> 0){ //取得需要被注入的bean实例 Object target = beanPool.get(propRef); //如果不存在 if(target == null){ //此处处理单例bean依赖于非单例bean的情形 } //定义设值注入需要的setter方法 Method setter = null; //遍历target对象所实现的所有方法 for(Class superInterface: target.getClass().getInterfaces()){ try{ //获取设置注入所需要的setter方法 setter = bean.getClass().getMethod("set"+propNameCamelize, superInterface); //如果成功获取,跳出循环 break; }catch (Exception e) { //如果没有找到就继续下次循环 continue; } } //如果setter方法依然是null,直接取得target的实现类对应的setter方法 if(setter == null){ setter = bean.getClass().getMethod("set"+propNameCamelize, target.getClass()); } //执行setter注入 setter.invoke(bean, target); } } } }}}

  

转载地址:http://moqyl.baihongyu.com/

你可能感兴趣的文章
Some lines about EF Code First migration.
查看>>
OPENId是什么, OAUTH 是什么
查看>>
Javascript的变量与delete操作符
查看>>
JDK8 Lambda表达式对代码的简化
查看>>
wpf 添加滚动条 ScrollViewer
查看>>
转载:Keytool 工具介绍
查看>>
[产品经理手记-02] 培训二三事
查看>>
个人作业 感想
查看>>
Cap15_知识管理
查看>>
【2012百度之星资格赛】F:百科蝌蚪团
查看>>
【解决方法】Ubuntu文本编辑器gedit打开中文出现乱码的
查看>>
【linux】ubuntu11.10下各种问题以及解决方案
查看>>
C++指针
查看>>
Python学习第一二章
查看>>
Docker学习笔记二:Docker常用命令及提升拉取镜像的速度
查看>>
Python操作Oracle
查看>>
Algs4-2.1.38不同类型的元素
查看>>
MapReduce源码分析总结(转)
查看>>
linux cpu、内存、硬盘空间查询
查看>>
idea 启动调试模式总提示端口58346被占用问题
查看>>