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<String,Object> beanPool=Collections.synchronizedMap(new HashMap<String,Object>());
//保存文件对应的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{
//遍历配置文件中的每个<bean ../>元素
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);
} }
} }
}
}

  

模拟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. Android系统移植与调试之------->如何修改Android设备添加重启、飞行模式、静音模式等功能(二)

    今天要说的是为Android设备添加重启.飞行模式.静音模式按钮,客户需求中需要添加这项功能,在长按电源键弹出的菜单中没有这些选项,谨以此文记录自己添加这个功能的过程. 首先找到长按电源键弹出的对话框 ...

  2. PAT 1063. 计算谱半径(20)

    在数学中,矩阵的“谱半径”是指其特征值的模集合的上确界.换言之,对于给定的n个复数空间的特征值{a1+b1i, ..., an+bni},它们的模为实部与虚部的平方和的开方,而“谱半径”就是最大模. ...

  3. IE11 for Windows 7 Enterprise With SP1 故障

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jaminwm/article/details/29592027 这个故障非常诡异,卸载IE11也没实 ...

  4. wecenter 问答社区 dockerfile,不用纠结于物理机的运行环境

    FROM webdevops/php-nginx:centos-7-php56 ADD . /app RUN ["chmod", "777", "/a ...

  5. 论文解析 "A Non-Local Cost Aggregation Method for Stereo Matching"

    传统的使用窗口的方法缺陷主要在 1.窗口外的像素不能参与匹配判断. 2.在低纹理区域很容易产生错误匹配 论文的主要贡献在代价聚类上(左右图像带匹配点/区域的匹配代价计算),目标是图像内所有点都对该点传 ...

  6. C# unicode GBK UTF-8和汉字互转

    界面: 源码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Da ...

  7. SpringBoot学习笔记(4):添加自定义的过滤器

    SpringBoot:学习笔记(4)——添加自定义的过滤器 引入自定义过滤器 SpringBoot提供的前端控制器无法满足我们产品的需求时,我们需要添加自定义的过滤器. SpringBoot添加过滤器 ...

  8. Never Go Away

    Hey if you ever want to leave it allif you ever want to lose control leave it all escape so far away ...

  9. JFreeChart的使用示例

    示例一,饼图,简单示例: 导入jar,代码文件: 运行结果: 代码: import org.jfree.chart.ChartFactory;import org.jfree.chart.ChartF ...

  10. unigui中TUniDBEdit的OnEndDrag问题

    非常奇怪,unigui中TUniDBEdit未发布OnEndDrag属性,包括其子类:TUniDBNumberEdit.TUniDBFormattedNumberEdit.而其他数据感知组件都有OnE ...