本文可作为北京尚学堂 spring课程的学习笔记

我们还是用上一篇文章的例子 给数据库中增加一个user

整体代码如下

  1. package com.bjsxt.test;
  2.  
  3. import com.bjsxt.dao.UserDaoMysql;
  4. import com.bjsxt.model.User;
  5. import com.bjsxt.services.UserService;
  6.  
  7. public class Test {
  8. public static void main(String[] args) {
  9. User user=new User();
  10. UserService userService=new UserService();
  11. UserDao dao=new UserDaoMysql();
  12. userService.setUserDao(dao);
  13. userService.Save(user);
  14. }
  15. }

上一个的test中 还是需要我写出

UserDao dao=new UserDaoMysql();

如果我想从xml中读出数据 以后可以不再改硬代码 如何?

首先写出xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans>
  3.  
  4. <bean id="u" class="com.bjsxt.dao.UserDaoMysql" />
  5.  
  6. </beans>

如果是oracle 也只用xml文件即可

现在我们需要做的就是读取xml  "自动"生成userdao 关于用jdom操作xml的只是 请看文章末尾的参考资料

我们现在要生产一个对象 那就是工厂模式嘛

  1. package com.bjsxt.spring;
  2.  
  3. public interface BeanFactory {
  4. public Object getBean(String id);
  5. }

再来一个操作xml的类

  1. package com.bjsxt.spring;
  2.  
  3. import java.io.IOException;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import org.jdom.Document;
  9. import org.jdom.Element;
  10. import org.jdom.JDOMException;
  11. import org.jdom.input.SAXBuilder;
  12.  
  13. public class ClassPathXmlApplicationContext implements BeanFactory {
  14.  
  15. Map<String, Object> map=new HashMap<String, Object>();
  16.  
  17. @SuppressWarnings("unchecked")
  18. public ClassPathXmlApplicationContext() throws JDOMException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
  19. SAXBuilder sb = new SAXBuilder();
  20. Document doc = sb.build(ClassPathXmlApplicationContext.class
  21. .getClassLoader().getResourceAsStream("spring.xml")); // 构造文档对象
  22. // Document doc=sb.build("d://test.xml"); //构造文档对象可以有两种方式 如果是在把xml文档放在
  23. //eclipse的根目录下 就有上面的方法
  24. Element root = doc.getRootElement(); // 获取根元素
  25.  
  26. List<Element> list = root.getChildren("bean");// 取名字为bean的所有元素
  27. for (int i = 0; i < list.size(); i++) {
  28. Element element = (Element) list.get(i);
  29. String name = element.getAttributeValue("id");
  30. String classPath = element.getAttributeValue("class");//取bean的元素class的内容
  31.  
  32. Object object=Class.forName(classPath).newInstance();
  33. map.put(name,object);
  34.  
  35. System.out.println("bean:");
  36. System.out.println("bean name: " + name);
  37. System.out.println("bean class: " + classPath);
  38.  
  39. System.out.println("———————————–");
  40. }
  41. }
  42.  
  43. @Override
  44. public Object getBean(String id) {
  45. return map.get(id);
  46. }
  47.  
  48. }

测试test如下

  1. package com.bjsxt.test;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.jdom.JDOMException;
  6.  
  7. import com.bjsxt.dao.UserDao;
  8. import com.bjsxt.dao.UserDaoMysql;
  9. import com.bjsxt.model.User;
  10. import com.bjsxt.services.UserService;
  11. import com.bjsxt.spring.ClassPathXmlApplicationContext;
  12.  
  13. public class Test {
  14. public static void main(String[] args) throws JDOMException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
  15. User user=new User();
  16. UserService userService=new UserService();
  17. ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext();
  18. Object object=context.getBean("u");
  19. userService.setUserDao((UserDao) object);
  20. userService.Save(user);
  21. }
  22. }

现在看看 上面的代码 我们还是有

userService.setUserDao((UserDao) object);

能不能吧userservice也从xml中读取 同时 它内部的属性也从xml中来

可以 那么xml首先得变成如下的样子

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans>
  3.  
  4. <bean id="u" class="com.bjsxt.dao.UserDaoMysql" />
  5.  
  6. <bean id="userService" class="com.bjsxt.services.UserService" >
  7. <property name="userDao" bean="u" />
  8. </bean>
  9.  
  10. </beans>

test测试函数应该是这样的

  1. package com.bjsxt.test;
  2.  
  3. import com.bjsxt.model.User;
  4. import com.bjsxt.services.UserService;
  5. import com.bjsxt.spring.ClassPathXmlApplicationContext;
  6.  
  7. public class Test {
  8.     public static void main(String[] args) throws Exception {
  9.         User user=new User();
  10.         
  11.         ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext();
  12.         UserService userService=(UserService) context.getBean("userService");
  13.         userService.Save(user);
  14.     }
  15. }

关键问题就是 ClassPathXmlApplicationContext内部怎么写

其实大家可以这样想 我在读取每一个bean的时候就看看它底下有没有参数 有的话就用反射技术 自动将属性装填进去

  1. package com.bjsxt.spring;
  2.  
  3. import java.lang.reflect.Method;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7.  
  8. import org.jdom.Document;
  9. import org.jdom.Element;
  10.  
  11. import org.jdom.input.SAXBuilder;
  12.  
  13. public class ClassPathXmlApplicationContext implements BeanFactory {
  14.  
  15. Map<String, Object> map = new HashMap<String, Object>();
  16.  
  17. @SuppressWarnings("unchecked")
  18. public ClassPathXmlApplicationContext() throws Exception {
  19. SAXBuilder sb = new SAXBuilder();
  20. Document doc = sb.build(ClassPathXmlApplicationContext.class
  21. .getClassLoader().getResourceAsStream("spring.xml")); // 构造文档对象
  22. // Document doc=sb.build("d://test.xml");
  23. Element root = doc.getRootElement(); // 获取根元素
  24.  
  25. List<Element> list = root.getChildren("bean");// 取名字为disk的所有元素
  26. for (int i = 0; i < list.size(); i++) {
  27. Element element = (Element) list.get(i);
  28. String name = element.getAttributeValue("id");
  29. String classPath = element.getAttributeValue("class");// 取disk子元素capacity的内容
  30.  
  31. Object object = Class.forName(classPath).newInstance();
  32. map.put(name, object);
  33.  
  34. for (Element propertyElement : (List<Element>) element
  35. .getChildren("property")) {
  36. String parameter = propertyElement.getAttributeValue("name"); // 获得userDao这个属性名称
  37. String bean = propertyElement.getAttributeValue("bean"); //就是xml里面的那个u
  38. Object obj = map.get(bean); //找到map里面的那个u
  39. //大家再试试把xml里面的两个bean的顺序调换一下 看有什么问题
  40. // 如何修改?
  41. String methodName = "set" //获得setUserDao这个方法名
  42. + parameter.substring(0, 1).toUpperCase()
  43. + parameter.substring(1);
  44. System.out.println(methodName);
  45. Method m = object.getClass().getMethod(methodName,
  46. obj.getClass().getInterfaces()[0]);
  47. // 查看getMethod的参数 String name, Class<?>... parameterTypes
  48. // 我们知道方法的名字是setUserDao 可问题是一个类中 可能出现重载情况 也就是方法名一样的情况
  49. // 所以后面的参数的意思就是 setUserDao的参数就是上面那个obj所实现的第一个接口
  50.  
  51. m.invoke(object, obj);
  52.  
  53. }
  54. }
  55. }
  56.  
  57. @Override
  58. public Object getBean(String id) {
  59. return map.get(id);
  60. }
  61.  
  62. }

ok 搞定 里面最麻烦的东西 我认为还是反射

这些代码 我认为初学者还是自己敲一遍比较好

参考资料

http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html

我也来写spring的更多相关文章

  1. 自己动手写spring容器(3)

    好久没有写博客了,今天闲下来将之前未完成的表达出来. 在之前的文章自己动手写spring容器(2)中完成了对spring的依赖注入的实现,这篇将会介绍spring基于注解的依赖注入的实现. 在一般的J ...

  2. 一个老程序员是如何手写Spring MVC的

    人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十 ...

  3. 【Spring】手写Spring MVC

    Spring MVC原理 Spring的MVC框架主要由DispatcherServlet.处理器映射.处理器(控制器).视图解析器.视图组成. 完整的Spring MVC处理 流程如下: Sprin ...

  4. 我是这样手写 Spring 的(麻雀虽小五脏俱全)

    人见人爱的 Spring 已然不仅仅只是一个框架了.如今,Spring 已然成为了一个生态.但深入了解 Spring 的却寥寥无几.这里,我带大家一起来看看,我是如何手写 Spring 的.我将结合对 ...

  5. 《四 spring源码》利用TransactionManager手写spring的aop

    事务控制分类 编程式事务控制          自己手动控制事务,就叫做编程式事务控制. Jdbc代码: Conn.setAutoCommite(false);  // 设置手动控制事务 Hibern ...

  6. 自己写spring boot starter

    自己写spring boot starter 学习了:<spring boot实战>汪云飞著 6.5.4节 pom.xml <project xmlns="http://m ...

  7. 手写 Spring

    手写 Spring 不多说,简历装 X 必备.不过练好还是需要求一定的思维能力. 一.整体思路 思路要熟练背下来 1)配置阶段 配置 web.xml: XDispatchServlet 设定 init ...

  8. 自己动手写Spring框架--IOC、MVC

    对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...

  9. 手写Spring框架,加深对Spring工作机制的理解!

    在我们的日常工作中,经常会用到Spring.Spring Boot.Spring Cloud.Struts.Mybatis.Hibernate等开源框架,有了这些框架的诞生,平时的开发工作量也是变得越 ...

  10. 手写Spring+demo+思路

    我在学习Spring的时候,感觉Spring是很难的,通过学习后,发现Spring没有那么难,只有你去学习了,你才会发现,你才会进步 1.手写Spring思路: 分为配置.初始化.运行三个阶段如下图 ...

随机推荐

  1. JVM常见问题 一(转载)

    1. 内存模型以及分区 JVM内存模型如下图所示: 此处我们集中注意中间绿色的部分,该部分为JVM的运行时内存,该部分包含了: 线程私有的(灰色): 程序计数器:记录执行到第几条指令 虚拟机方法栈:执 ...

  2. Mysql中where条件一个单引号引发的性能损耗

    日常写SQL中可能会有一些小细节忽略了导致整个sql的性能下降了好几倍甚至几十倍,几百倍.以下这个示例就是mysql语句中的一个单引号('')引发的性能耗损,我相信很多朋友都遇到过,甚至还在这样写. ...

  3. 列表ListBox、ListView、GridView 排序

    列表排序 1.使用控件默认排序方式(推荐) ListControl.Items.SortDescriptions.Clear(); ListControl.Items.SortDescriptions ...

  4. WIN2008虚拟机安装ORACLE11g记录

    ---恢复内容开始--- 1.ORACLE11g的安装包下载与解压 官网下载地址:(http://www.oracle.com/technetwork/database/enterprise-edit ...

  5. UDP网络编程

    概念: UDP协议(用户数据报协议)是无连接,不可靠的,无序的.速度比较快, UDP协议以数据报作为数据传输的载体 进行数据传输时,首先将传输的数据定义成数据报(Datagram),在数据报中指明数据 ...

  6. SimpleDateFormat中parse和format的区别

    parse()返回的是一个Date类型数据,format返回的是一个StringBuffer类型的数据 //SimpleDateFormat中的parse方法可以 //把String型的字符串转换成特 ...

  7. sklearn:最近邻搜索sklearn.neighbors

    http://blog.csdn.net/pipisorry/article/details/53156836 ball tree k-d tree也有问题[最近邻查找算法kd-tree].矩形并不是 ...

  8. 有无序的实数列V[N],要求求里面大小相邻的实数的差的最大值,关键是要求线性空间和线性时间。

    int findMaxDifBt2Nums(int* arr, int len) { int maxItem = arr[0], minItem = arr[0]; for (int i = 1; i ...

  9. Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...

  10. lucene内存索引库、分词器

    内存索引库 特点 在内存中开辟一块空间,专门为索引库存放.这样有以下几个特征: 1)    因为索引库在内存中,所以访问速度更快. 2)    在程序退出时,索引库中的文件也相应的消失了. 3)    ...