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);
}
}
}
}
}
}