1. package com.xiaohao.action;
  2.  
  3. import java.io.File;
  4. import java.lang.reflect.Method;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8.  
  9. import org.dom4j.Document;
  10. import org.dom4j.Element;
  11. import org.dom4j.io.SAXReader;
  12.  
  13. /**
  14. * 需要导入dom4j的jar包
  15. * @author 小浩
  16. * @创建日期 2015-4-4
  17. */
  18. public class BeanFactory {
  19.  
  20. /**
  21. * 保存容器中所有单例模式的bean实例,这里的hashMap是线程安全的
  22. *
  23. */
  24.  
  25. private static Map<String,Object> beanPool=Collections.synchronizedMap(new HashMap<String,Object>());
  26. //保存文件对应的Document对象
  27. private Document document;
  28. //保存配置文件里的根元素
  29. private Element root;
  30.  
  31. /**
  32. * 构造方法,指定需要读取的文件的路径
  33. * @param filePath
  34. * @throws Exception
  35. */
  36. public BeanFactory(String filePath) throws Exception{
  37.  
  38. //使用dom4j读取xml配置文件
  39. SAXReader reader=new SAXReader();
  40. document=reader.read(new File(filePath));
  41. root=document.getRootElement();
  42. //进行容器的初始化
  43. initPool();
  44. //初始化单例bean的属性
  45. initProp();
  46.  
  47. }
  48.  
  49. /**
  50. * 获取指定的bean
  51. * @param name
  52. * @return
  53. * @throws Exception
  54. */
  55. public static Object getBean(String name) throws Exception {
  56. Object target = beanPool.get(name);
  57. //对于单例bean,容器已经初始化了所有的Bean实例
  58. if(target.getClass() != String.class){
  59. return target;
  60. }else{
  61. String clazz = (String)target;
  62. //对于非单例的并未注入属性值
  63. return Class.forName(clazz).newInstance();
  64. }
  65.  
  66. }
  67.  
  68. /**
  69. * 初始化容器中的所有单例bean
  70. * */
  71. private void initPool() throws Exception{
  72. //遍历配置文件中的每个<bean ../>元素
  73. for(Object obj:root.elements()){
  74. Element beanElement = (Element)obj;
  75. //获取Bean元素中的id属性
  76. String beanId = beanElement.attributeValue("id");
  77. //获取bean元素中的class属性
  78. String beanClazz = beanElement.attributeValue("class");
  79. //获取bean元素中的scope属性
  80. String beanScope = beanElement.attributeValue("scope");
  81. //如果scope属性不存在或为singleton
  82. if(beanScope == null|| beanScope.equals("singleton")){
  83. //以默认构造方法创建bean实例,并将其放入beanPool中
  84. beanPool.put(beanId, Class.forName(beanClazz).newInstance()); //利用反射的技术
  85. }else{
  86. //对于非单例的,存放Bean实现类的类名
  87. beanPool.put(beanId, beanClazz);
  88. }
  89. }
  90.  
  91. }
  92.  
  93. /**
  94. * 初始化容器中的单例bean
  95. * */
  96. private void initProp() throws Exception{
  97. //遍历配置文件中的所有bean元素,即根节点的子节点
  98. for(Object object:root.elements()){
  99. Element beanElement = (Element)object;
  100. //获取Bean元素中的id属性
  101. String beanId = beanElement.attributeValue("id");
  102. //获取bean元素中的scope属性
  103. String beanScope = beanElement.attributeValue("scope");
  104. //如果scope属性不存在或为singleton
  105. if(beanScope == null|| beanScope.equals("singleton")){
  106. //取出beanPool的指定bean实例
  107. Object bean = beanPool.get(beanId);
  108. //遍历bean属性下的所有property属性
  109. for(Object prop: beanElement.elements()){
  110. Element probElement = (Element)prop;
  111. //获取property的name属性
  112. String propName = probElement.attributeValue("name");
  113. //获取property的value属性
  114. String propValue = probElement.attributeValue("value");
  115. //获取property的ref属性
  116. String propRef = probElement.attributeValue("ref");
  117. //将属性名的首字母大写
  118. String propNameCamelize = propName.substring(0,1).toUpperCase()
  119. +propName.substring(1, propName.length());
  120. //如果value值存在
  121. if(propValue != null&&propValue.length()> 0){
  122. //获取设置注入所需要的setter方法
  123. java.lang.reflect.Method setter = bean.getClass().getMethod("set"+propNameCamelize, String.class);
  124. //执行setter注入
  125. setter.invoke(bean, propValue);
  126. }
  127. if(propRef != null&&propRef.length()> 0){
  128. //取得需要被注入的bean实例
  129. Object target = beanPool.get(propRef);
  130. //如果不存在
  131. if(target == null){
  132. //此处处理单例bean依赖于非单例bean的情形
  133. }
  134. //定义设值注入需要的setter方法
  135. Method setter = null;
  136. //遍历target对象所实现的所有方法
  137. for(Class superInterface: target.getClass().getInterfaces()){
  138. try{
  139. //获取设置注入所需要的setter方法
  140. setter = bean.getClass().getMethod("set"+propNameCamelize, superInterface);
  141. //如果成功获取,跳出循环
  142. break;
  143. }catch (Exception e) {
  144. //如果没有找到就继续下次循环
  145. continue;
  146. }
  147. }
  148. //如果setter方法依然是null,直接取得target的实现类对应的setter方法
  149. if(setter == null){
  150. setter = bean.getClass().getMethod("set"+propNameCamelize, target.getClass());
  151. }
  152. //执行setter注入
  153. setter.invoke(bean, target);
  154. }
  155.  
  156. }
  157. }
  158.  
  159. }
  160. }
  161. }

  

模拟Spring中applicationContext.xml配置文件初始化bean的过程的更多相关文章

  1. ssh整合思想初步 struts2与Spring的整合 struts2-spring-plugin-2.3.4.1.jar下载地址 自动加载Spring中的XML配置文件 Struts2下载地址

    首先需要JAR包 Spring整合Structs2的JAR包 struts2-spring-plugin-2.3.4.1.jar 下载地址 链接: https://pan.baidu.com/s/1o ...

  2. web.xml中配置Spring中applicationContext.xml的方式

    2011-11-08 16:29 web.xml中配置Spring中applicationContext.xml的方式 使用web.xml方式加载Spring时,获取Spring applicatio ...

  3. 关于Spring中applicationContext.xml配置错误“org/springframework/transaction/interceptor/TransactionInterceptor”的问题解决

    问题描述: 在配置spring的applicationContext.xml中的默认事务管理器的时候可能会出现这样的错误: Error occured processing XML 'org/spri ...

  4. Spring中applicationContext.xml详解

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. 关于spring的applicationContext.xml配置文件的ref和value之自我想法

    今天在做SSH的一个项目的时候,因为需要定时操作,所以就再sping里面加入了一个quartz的小定时框架,结果在运行时候,发生了一个小bug. Caused by: org.springframew ...

  6. Spring中applicationContext.xml的bean里的id和name属性区别

    转自:http://www.cnblogs.com/ztf2008/archive/2009/02/11/1388003.html <beans><bean id="per ...

  7. STS中applicationContext.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  8. Spring中,applicationContext.xml 配置文件在web.xml中的配置详解

    一.首先写一下代码结构. 二.再看web.xml中的配置情况. <?xml version="1.0" encoding="UTF-8"?> < ...

  9. Spring中ApplicationContext加载机制和配置初始化

    Spring中ApplicationContext加载机制.        加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet.        ...

随机推荐

  1. 几则js表达式

    过滤大段文本里的标签.标签格式 <...>,如下匹配标签然后替换成空 校验邮箱是否符合: 去掉行首行尾空格: 检测字符串是否包含中文:(utf8编码)

  2. Linux安装Nginx使用负载均衡

    1.实验准备准备三台计算机 nginx1 192.168.13.121 作为nginx负载均衡器nginx2 192.168.13.24  web服务,提供一个页面        nginx3 192 ...

  3. SAP 定价

    近几天做门店团购销售订单上传SAP接口程序,SO创建测试过程中, 遇到定价问题,同事在定价过程的增强过不了. VOFM 了解到定价过程是个非常复杂的环节,此处出现程序处理过程中ZMP0定价条件下的价格 ...

  4. shell基础part1

    shell基础一 一.什么是shell shell是个功能强大的编程语言,也是个解释执行的脚本语言(命令解释器). 二.shell分类 1.bourne shell (包括sh.ksh.Bash.ps ...

  5. VMware下所有的系统网卡启动不起来

    昨天新装了一台Linux,装好之后网络起不来,搞了半天也没弄好,总是报错: Failed to start LSB: Bring up/down networking.... 我以为是我的设置出了问题 ...

  6. 通过systemd配置Docker

    1. systemd Service相关目录 通常情况下,我们有3种方式可以配置etcd中的service.以docker为例,1)在目录/etc/systemd/system/docker.serv ...

  7. || and && 理解

    逻辑或(||): 只要第一个值的布尔值为false,那么永远返回第二个值. 逻辑或属于短路操作,第一个值为true时,不再操作第二个值,且返回第一个值. 逻辑与(&&): 只要第一个值 ...

  8. MVC ViewBag不能使用在工程文件中添加引用

    在工程文件中 <ItemGroup> // ... </ItemGroup> 添加引用 <Reference Include="Microsoft.CSharp ...

  9. iOS 8以后 定位手动授权问题

    ios8以后 都是手动授权定位权限 不过不处理这块 在ios8以后的系统就会默认永不授权 即关闭了定位权限 处理办法如下 .导入框架头文件 #import <CoreLocation/CoreL ...

  10. Ansible 实战之部署Web架构

    WEB架构(ubuntu 16.04): Proxy -- WebServer(Nginx+PHP+Django) -- Nosql -- MariaDB 一. 定义Inventory [proxy] ...