我也来写spring
本文可作为北京尚学堂 spring课程的学习笔记
我们还是用上一篇文章的例子 给数据库中增加一个user
整体代码如下
package com.bjsxt.test; import com.bjsxt.dao.UserDaoMysql; import com.bjsxt.model.User; import com.bjsxt.services.UserService; public class Test { public static void main(String[] args) { User user=new User(); UserService userService=new UserService(); UserDao dao=new UserDaoMysql(); userService.setUserDao(dao); userService.Save(user); } }
上一个的test中 还是需要我写出
UserDao dao=new UserDaoMysql();
如果我想从xml中读出数据 以后可以不再改硬代码 如何?
首先写出xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="u" class="com.bjsxt.dao.UserDaoMysql" /> </beans>
如果是oracle 也只用xml文件即可
现在我们需要做的就是读取xml "自动"生成userdao 关于用jdom操作xml的只是 请看文章末尾的参考资料
我们现在要生产一个对象 那就是工厂模式嘛
package com.bjsxt.spring; public interface BeanFactory { public Object getBean(String id); }
再来一个操作xml的类
package com.bjsxt.spring; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class ClassPathXmlApplicationContext implements BeanFactory { Map<String, Object> map=new HashMap<String, Object>(); @SuppressWarnings("unchecked") public ClassPathXmlApplicationContext() throws JDOMException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(ClassPathXmlApplicationContext.class .getClassLoader().getResourceAsStream("spring.xml")); // 构造文档对象 // Document doc=sb.build("d://test.xml"); //构造文档对象可以有两种方式 如果是在把xml文档放在 //eclipse的根目录下 就有上面的方法 Element root = doc.getRootElement(); // 获取根元素 List<Element> list = root.getChildren("bean");// 取名字为bean的所有元素 for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); String name = element.getAttributeValue("id"); String classPath = element.getAttributeValue("class");//取bean的元素class的内容 Object object=Class.forName(classPath).newInstance(); map.put(name,object); System.out.println("bean:"); System.out.println("bean name: " + name); System.out.println("bean class: " + classPath); System.out.println("———————————–"); } } @Override public Object getBean(String id) { return map.get(id); } }
测试test如下
package com.bjsxt.test; import java.io.IOException; import org.jdom.JDOMException; import com.bjsxt.dao.UserDao; import com.bjsxt.dao.UserDaoMysql; import com.bjsxt.model.User; import com.bjsxt.services.UserService; import com.bjsxt.spring.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) throws JDOMException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { User user=new User(); UserService userService=new UserService(); ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(); Object object=context.getBean("u"); userService.setUserDao((UserDao) object); userService.Save(user); } }
现在看看 上面的代码 我们还是有
userService.setUserDao((UserDao) object);
能不能吧userservice也从xml中读取 同时 它内部的属性也从xml中来
可以 那么xml首先得变成如下的样子
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="u" class="com.bjsxt.dao.UserDaoMysql" /> <bean id="userService" class="com.bjsxt.services.UserService" > <property name="userDao" bean="u" /> </bean> </beans>
test测试函数应该是这样的
package com.bjsxt.test; import com.bjsxt.model.User; import com.bjsxt.services.UserService; import com.bjsxt.spring.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) throws Exception { User user=new User(); ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(); UserService userService=(UserService) context.getBean("userService"); userService.Save(user); } }
关键问题就是 ClassPathXmlApplicationContext内部怎么写
其实大家可以这样想 我在读取每一个bean的时候就看看它底下有没有参数 有的话就用反射技术 自动将属性装填进去
package com.bjsxt.spring; import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; public class ClassPathXmlApplicationContext implements BeanFactory { Map<String, Object> map = new HashMap<String, Object>(); @SuppressWarnings("unchecked") public ClassPathXmlApplicationContext() throws Exception { SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(ClassPathXmlApplicationContext.class .getClassLoader().getResourceAsStream("spring.xml")); // 构造文档对象 // Document doc=sb.build("d://test.xml"); Element root = doc.getRootElement(); // 获取根元素 List<Element> list = root.getChildren("bean");// 取名字为disk的所有元素 for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); String name = element.getAttributeValue("id"); String classPath = element.getAttributeValue("class");// 取disk子元素capacity的内容 Object object = Class.forName(classPath).newInstance(); map.put(name, object); for (Element propertyElement : (List<Element>) element .getChildren("property")) { String parameter = propertyElement.getAttributeValue("name"); // 获得userDao这个属性名称 String bean = propertyElement.getAttributeValue("bean"); //就是xml里面的那个u Object obj = map.get(bean); //找到map里面的那个u //大家再试试把xml里面的两个bean的顺序调换一下 看有什么问题 // 如何修改? String methodName = "set" //获得setUserDao这个方法名 + parameter.substring(0, 1).toUpperCase() + parameter.substring(1); System.out.println(methodName); Method m = object.getClass().getMethod(methodName, obj.getClass().getInterfaces()[0]); // 查看getMethod的参数 String name, Class<?>... parameterTypes // 我们知道方法的名字是setUserDao 可问题是一个类中 可能出现重载情况 也就是方法名一样的情况 // 所以后面的参数的意思就是 setUserDao的参数就是上面那个obj所实现的第一个接口 m.invoke(object, obj); } } } @Override public Object getBean(String id) { return map.get(id); } }
ok 搞定 里面最麻烦的东西 我认为还是反射
这些代码 我认为初学者还是自己敲一遍比较好
参考资料
http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html
我也来写spring的更多相关文章
- 自己动手写spring容器(3)
好久没有写博客了,今天闲下来将之前未完成的表达出来. 在之前的文章自己动手写spring容器(2)中完成了对spring的依赖注入的实现,这篇将会介绍spring基于注解的依赖注入的实现. 在一般的J ...
- 一个老程序员是如何手写Spring MVC的
人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十 ...
- 【Spring】手写Spring MVC
Spring MVC原理 Spring的MVC框架主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成. 完整的Spring MVC处理 流程如下: Sprin ...
- 我是这样手写 Spring 的(麻雀虽小五脏俱全)
人见人爱的 Spring 已然不仅仅只是一个框架了.如今,Spring 已然成为了一个生态.但深入了解 Spring 的却寥寥无几.这里,我带大家一起来看看,我是如何手写 Spring 的.我将结合对 ...
- 《四 spring源码》利用TransactionManager手写spring的aop
事务控制分类 编程式事务控制 自己手动控制事务,就叫做编程式事务控制. Jdbc代码: Conn.setAutoCommite(false); // 设置手动控制事务 Hibern ...
- 自己写spring boot starter
自己写spring boot starter 学习了:<spring boot实战>汪云飞著 6.5.4节 pom.xml <project xmlns="http://m ...
- 手写 Spring
手写 Spring 不多说,简历装 X 必备.不过练好还是需要求一定的思维能力. 一.整体思路 思路要熟练背下来 1)配置阶段 配置 web.xml: XDispatchServlet 设定 init ...
- 自己动手写Spring框架--IOC、MVC
对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...
- 手写Spring框架,加深对Spring工作机制的理解!
在我们的日常工作中,经常会用到Spring.Spring Boot.Spring Cloud.Struts.Mybatis.Hibernate等开源框架,有了这些框架的诞生,平时的开发工作量也是变得越 ...
- 手写Spring+demo+思路
我在学习Spring的时候,感觉Spring是很难的,通过学习后,发现Spring没有那么难,只有你去学习了,你才会发现,你才会进步 1.手写Spring思路: 分为配置.初始化.运行三个阶段如下图 ...
随机推荐
- [ Java学习基础 ] Java的抽象类与接口
一.抽象类 1. 抽象类 Java语言提供了两种类:一种是具体类:另一种是抽象子类. 2. 抽象类概念: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的 ...
- JAVA GC垃圾收集器的分析
本篇文章主要介绍了"JAVA GC垃圾收集器的分析",主要涉及到JAVA GC垃圾收集器的分析方面的内容,对于JAVA GC垃圾收集器的分析感兴趣的同学可以参考一下. ...
- 利用mybatis-generator自动生成数据持久化的代码
MyBatis生成器简介 MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器.它将生成所有版本的MyBatis的代码,以及版本2.2.0之后的iB ...
- LINUX逻辑卷(LVM)管理与逻辑卷分区
LINUX之逻辑卷管理与逻辑卷扩展 LVM是逻辑卷管理(Logical Volume Manager)的简称,他是建立在物理存储设备之上的一个抽象层,允许你生成逻辑存储卷,和直接使用物理存储在管理上相 ...
- 原生Js写轮播图代码
html css js 在知道jQuery如何实现轮播效果的基础上,用js写代码 如图:标记这里的地方 理解一下 用到的知识: 1.HTML DOM 的appendChild() 和 removeCh ...
- C++框架_之Qt的窗口部件系统的详解-上
C++框架_之Qt的窗口部件系统的详解-上 第一部分概述 第一次建立helloworld程序时,曾看到Qt Creator提供的默认基类只有QMainWindow.QWidget和QDialog三种. ...
- Java第8次实验(IO流)
参考资料 本次作业参考文件 正则表达式参考资料 第1次实验 1. 字符流与文本文件:使用 PrintWriter(写),BufferedReader(读) 参考文件:基础代码目录Student.jav ...
- OC基础之可循环滚动并突出中间图片,并且可点击
前两天一哥们儿让我帮他写一下:可循环滚动并突出中间图片,并且可点击的一种滑动视图的效果,今天放在这里给大家展示一下,具体文字代码中都有注解,代码还有待完善,不喜勿喷,转载请注明,下载请点星,谢谢~ - ...
- Rails里rake db:migrate出现undefined method last_comment问题的解决
这个问题和特定的rake版本有关,因为Rails要使用rake的last_comment方法在较新版本的rake中已被废弃,所以很多人卸载了新版本的rake去安装旧版本的rake. 这样也能解决问题, ...
- Zookeeper的功能以及工作原理 (转自:http://www.cnblogs.com/felixzh/p/5869212.html)
1.ZooKeeper是什么?ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的 ...