拿起笔来做刀枪 · 之二 再造一个spring
2014-07-28 14:48
399 查看
首先回顾一下我在前面章节提到的内容:
开发,从需求出发 · 之四 春天在这里
我们离spring的内容只有一步之遥,正如前文所说:
请比较和spring.xml的区别:
好吧,没什么根本上的区别,我们同样能够解析xml,得到我们自己实现的BeanFactory所需要的一切要素。
由于有前一章的基础,我们只需要调用实现的 XmlParser进行整合就可以了:)
请遵守另一个原则,“不要想太多,从最简单的实现”入手。
我们其实需要的仅仅是一个 适配器,Adaptor。
让我们通过代码硬编码赋值进去的内容变成 首先解析xml,然后再赋值给:
由此,先得到方法:
然后,读取xml,解析,然后将获得的根节点传入:
最后,我们和BeanFactory进行整合:
最终,我们得到了一个类似spring 的类装配和组织框架。
当然,它相当简陋,不过,足够我们阐述清楚问题,并在我们的项目sitefromscratch中使用。
如果继续向spring靠拢,比如,我们要实现 spring的
并不是一件很困难的工作,当然,我无意去“重复发明轮子”,我的目的是通过一个自己的实现去尝试理解成熟框架的实现机制和思想。
开发,从需求出发 · 之四 春天在这里
我们离spring的内容只有一步之遥,正如前文所说:private static Map<String, String> appBean = new HashMap<String, String>(); private static Map<String, String[]> appRef = new HashMap<String, String[]>(); static { appBean.put("luceneDAO", "cn.com.sitefromscrath.dao.LuceneDAOMock"); appBean.put("mysqlDAO", "cn.com.sitefromscrath.dao.MysqlDAOMock"); appBean.put("searchService", "cn.com.sitefromscrath.service.SearchServiceInRealBiz"); appRef.put("searchService", new String[]{"luceneDAO", "mysqlDAO"}); }
请比较和spring.xml的区别:
<?xml version="1.0" encoding="UTF-8"?> <beans > <bean id="luceneDAO" class="cn.com.sitefromscrath.dao.LuceneDAOMock" /> <bean id="mysqlDAO" class="cn.com.sitefromscrath.dao.MysqlDAOMock" /> <bean id="searchService" class="cn.com.sitefromscrath.service.SearchServiceInRealBiz"> <constructor-arg index="1" ref="luceneDAO" /> <constructor-arg index="2" ref="mysqlDAO" /> </bean> </beans>
好吧,没什么根本上的区别,我们同样能够解析xml,得到我们自己实现的BeanFactory所需要的一切要素。
由于有前一章的基础,我们只需要调用实现的 XmlParser进行整合就可以了:)
请遵守另一个原则,“不要想太多,从最简单的实现”入手。
我们其实需要的仅仅是一个 适配器,Adaptor。
让我们通过代码硬编码赋值进去的内容变成 首先解析xml,然后再赋值给:
private static Map<String, String> appBean = new HashMap<String, String>(); private static Map<String, String[]> appRef = new HashMap<String, String[]>();
由此,先得到方法:
public static void fillAppInitParams(Node root){ for(int i = 0; i < root.getChildren().size(); i++) { Node bean = (Node) root.getChildren().get(i); String id = bean.getAttributes().get("id"); String clazz = bean.getAttributes().get("class"); appBean.put(id, clazz); if(!bean.getChildren().isEmpty()) { List<String> refs = new ArrayList<String>(); for(int k = 0; k < bean.getChildren().size(); k++) { Node arg = (Node)bean.getChildren().get(k); refs.add(arg.getAttributes().get("ref")); } appRef.put(id, refs.toArray(new String[0])); } } }
然后,读取xml,解析,然后将获得的根节点传入:
public static void init() { try { XmlParser xmlParser = new XmlParser(); InputStream is = xmlParser.getClass().getResourceAsStream("./test.xml"); DomTree dt = xmlParser.build(is); is.close(); fillAppInitParams(dt.getRoot()); } catch (Exception e) { e.printStackTrace(); } }
最后,我们和BeanFactory进行整合:
package net.csdn.blog.deltatang; import java.io.InputStream; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import net.csdn.blog.deltatang.dom4me.DomTree; import net.csdn.blog.deltatang.dom4me.Node; import net.csdn.blog.deltatang.dom4me.XmlParser; public class BeanFactory { private static boolean initSucc = false; private static Map<String, String> appBean = new HashMap<String, String>(); private static Map<String, String[]> appRef = new HashMap<String, String[]>(); public static void fillAppInitParams(Node root){ for(int i = 0; i < root.getChildren().size(); i++) { Node bean = (Node) root.getChildren().get(i); String id = bean.getAttributes().get("id"); String clazz = bean.getAttributes().get("class"); appBean.put(id, clazz); if(!bean.getChildren().isEmpty()) { List<String> refs = new ArrayList<String>(); for(int k = 0; k < bean.getChildren().size(); k++) { Node arg = (Node)bean.getChildren().get(k); refs.add(arg.getAttributes().get("ref")); } appRef.put(id, refs.toArray(new String[0])); } } } public static void init() { try { XmlParser xmlParser = new XmlParser(); InputStream is = xmlParser.getClass().getResourceAsStream("./test.xml"); DomTree dt = xmlParser.build(is); is.close(); fillAppInitParams(dt.getRoot()); } catch (Exception e) { e.printStackTrace(); } } public static Object getBean(String id) { if(initSucc) { init(); initSucc = true; } try { String className = appBean.get(id); Class clazz = Class.forName(className); Constructor constructor; String[] ref = appRef.get(id); if(ref == null || ref.length == 0) { constructor = clazz.getConstructor(); return (Object)constructor.newInstance(); } Class[] parameterTypes = new Class[ref.length]; Object[] initargs = new Object[ref.length]; for(int i = 0; i < ref.length; i++) { String r = ref[i]; String rclassName = appBean.get(r); parameterTypes[i] = Class.forName(rclassName).getInterfaces()[0]; //这里我偷懒了:) initargs[i] = getBean(r); } constructor = clazz.getConstructor(parameterTypes); return (Object)constructor.newInstance(initargs); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String ... arg) { LuceneDAO luceneDAO = (LuceneDAO) getBean("luceneDAO"); int[] vals = luceneDAO.findDocIDs("test"); for(int v : vals) { System.out.println(v); } String keywords = "test"; SearchService searchService = (SearchService)getBean("searchService"); List results = searchService.search(keywords); for(int i = 0; i < results.size(); i++) { Result result = (Result) results.get(i); System.out.print("[" + result.title + "]"); System.out.println(result.content); } } }
最终,我们得到了一个类似spring 的类装配和组织框架。
当然,它相当简陋,不过,足够我们阐述清楚问题,并在我们的项目sitefromscratch中使用。
如果继续向spring靠拢,比如,我们要实现 spring的
singlton="flase" lazy="true"
并不是一件很困难的工作,当然,我无意去“重复发明轮子”,我的目的是通过一个自己的实现去尝试理解成熟框架的实现机制和思想。
相关文章推荐
- 拿起笔来做刀枪 · 之一 再造一个dom4j
- 拿起笔来做刀枪 · 之四 再造一个struts
- 拿起笔来做刀枪 · 之五 再造一个lucene
- 拿起笔来做刀枪 · 之三 再造一个jsp(java sign pages)
- 拿起笔来做刀枪 · 之六 再造一个hibernate
- 拿起笔来做刀枪 · 序言
- 拿起笔来做刀枪 · 之七 最终幻想 Final Fantasy
- 如何捕捉短线(一个局外人的思考与联想)待续···
- 写一个sql中视图和存储过程的简单创建和调用方法!!!自我备忘用····
- javascript入门·脚本执行的时间的四种类型(赠送一个转换的小例题)
- 自己写了一个小的计算器···
- 怎么样从一个疯狂下载者成为一个学习者!!!值得反省下的问题·~~
- 苹果史蒂夫·乔布斯辞世 一个传奇时代的终结
- 一个博士的悲情经历~失败的经验最美···小木虫上的系列精华帖(科研的、被科研的,共勉。转载,个人整理)
- 《编程导论(Java)·例程》tips.Print的一个bug
- 切·格瓦拉 ———— 一个英雄的一生!
- Spring的MethodBeforeAdvice实现原理探究&&实现一个简单的Advice
- 刷 百度排名,百度(google)搜索提示下拉关联词的一个简易思路··
- 将一个数插入数组并排序·····信答案还不如信自己!!!
- ·用MyEclipse开发spring入门--图