在一家公司实习,用到了SPRING 框架,感觉自己也能实现这样的框架,就这么决定了,一步步满满实现它(虽然十有八九会失败。。)
先试一下实现 BEANFACTORY 吧
首先试着解析这样的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="base" class="com.lee.bean.BaseBean">
<property id="sub" ref="sub" />
</bean>
<bean id="sub" class="com.lee.bean.SubBean"/>
</beans>
其中 base中有一个属性为sub,为是d=sub SubBean的引用
实现的代码如下:
package beanfactory;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.lee.bean.BaseBean;
import com.lee.bean.SubBean;
public class BeanFactory {
private static Map<String, Object> map = null;
private static SAXReader sax = null;
private static Document doc = null;
static {
init();
}
/*
* 获取BEAN
*/
public static Object getBean(String name) throws Exception {
Object obj = map.get(name);
if (obj == null)
throw new Exception("NO SUCH BEAN");
return obj;
}
/*
* 初始化BEAN工厂
*/
public static void init() {
try {
if (map == null)
map = new HashMap<String, Object>();
sax = new SAXReader();
File f = new File(BeanFactory.class.getClassLoader()
.getResource("config/config.xml").toURI());
doc = sax.read(f);
Element root = doc.getRootElement();
generateBeans(root);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
SubBean sub = (SubBean) BeanFactory.getBean("sub");
sub.sayHello();
BaseBean base = (BaseBean) BeanFactory.getBean("base");
base.sayHello();
base.getSub().sayHello();
}
/*
* 解析config.xml 生成BEAN
*/
private static void generateBeans(Element root) throws Exception {
List<?> lst = root.elements();
for (int i = 0; i < lst.size(); i++) {
Element e = (Element) lst.get(i);
generateBean(e);
List<?> list = e.elements();
//处理引用BEAN
for (int j = 0; j < list.size(); j++) {
Element ee = (Element) list.get(j);
String name = ee.attributeValue("id");//得到属性名称
String ref = ee.attributeValue("ref");//获取引用id
Object sub = map.get(ref);
if (sub == null) {
Element se = (Element) (doc
.selectSingleNode("beans/bean[@id='" + ref + "']"));
sub = generateBean(se);
}
String clazz = e.attributeValue("class");
Class<?> clz = Class.forName(clazz);
Object base = map.get(e.attributeValue("id"));
String set = name.substring(0, 1).toUpperCase()
+ name.substring(1);
Method method = clz.getDeclaredMethod("set" + set,
new Class[] { sub.getClass() });
method.invoke(base, new Object[] { sub });//反射实现赋值
}
}
}
/*
* 生成单个BEAN
*/
private static Object generateBean(Element e) throws Exception {
String name = e.attributeValue("id");
if (map.get(name) != null)
return null;
String clazz = e.attributeValue("class");
Object obj = Class.forName(clazz).newInstance();
map.put(name, obj);
return obj;
}
}
OK了 代码注释略少,但是关键地方还是有的。
因为本人没有什么工程经验,所以只是按着自己的理解来实现的,希望大家能够指出不足。