http://blog.csdn.net/yerenyuan_pku/article/details/52832434

在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进行管理,并且明白了怎么从Spring容器中获取bean。那我们就有一个疑问了:Spring是如何创建并管理bean的呢?现在我们就来编码剖析Spring管理Bean的原理。 
本文是在Spring的第一个案例的基础上展开的。 
我们要使用dom4j读取Sping的配置文件——beans.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>
  7. </beans>

那么就需要将dom4j所需的jar包导入该项目中。dom4j所需的jar包为:

  • dom4j-1.6.1.jar
  • jaxen-1.1-beta-6.jar

dom4j读取到诸如

  1. <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>
  • 1
  • 1

这样的内容时,务必需要将读取到的bean的信息存到一个JavaBean对象中。于是我们可在junit.test包下创建这样一个JavaBean——BeanDefinition.java,其代码为:

  1. /**
  2. * 将读取到的bean的信息存到一个JavaBean对象中
  3. * @author li ayun
  4. *
  5. */
  6. public class BeanDefinition {
  7. private String id;
  8. private String className;
  9. public BeanDefinition(String id, String className) {
  10. this.id = id;
  11. this.className = className;
  12. }
  13. public String getId() {
  14. return id;
  15. }
  16. public void setId(String id) {
  17. this.id = id;
  18. }
  19. public String getClassName() {
  20. return className;
  21. }
  22. public void setClassName(String className) {
  23. this.className = className;
  24. }
  25. }

接下来我们就创建一个传智播客版的Spring容器来模拟Spring容器。在junit.test下新建一个类——ItcastClassPathXMLApplicationContext.java,其代码如下:

  1. /**
  2. * 传智播客版Spring容器
  3. * @author li ayun
  4. *
  5. */
  6. public class ItcastClassPathXMLApplicationContext {
  7. private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
  8. private Map<String, Object> sigletons = new HashMap<String, Object>();
  9. public ItcastClassPathXMLApplicationContext(String filename) {
  10. this.readXML(filename);
  11. this.instanceBeans();
  12. }
  13. /**
  14. * 完成bean的实例化
  15. */
  16. private void instanceBeans() {
  17. for (BeanDefinition beanDefinition : beanDefines) {
  18. try {
  19. if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) {
  20. sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
  21. }
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }
  27. /**
  28. * 读取XML配置文件
  29. * @param filename
  30. */
  31. private void readXML(String filename) {
  32. SAXReader saxReader = new SAXReader();
  33. Document document = null;
  34. try {
  35. URL xmlpath = this.getClass().getClassLoader().getResource(filename);
  36. document = saxReader.read(xmlpath);
  37. Map<String, String> nsMap = new HashMap<String, String>();
  38. nsMap.put("ns", "http://www.springframework.org/schema/beans"); // 加入命名空间
  39. XPath xsub = document.createXPath("//ns:beans/ns:bean"); // 创建beans/bean查询路径
  40. xsub.setNamespaceURIs(nsMap); // 设置命名空间
  41. List<Element> beans = xsub.selectNodes(document); // 获取文档下所有bean节点
  42. for (Element element : beans) {
  43. String id = element.attributeValue("id"); // 获取id属性值
  44. String clazz = element.attributeValue("class"); // 获取class属性值
  45. BeanDefinition beanDefine = new BeanDefinition(id, clazz);
  46. beanDefines.add(beanDefine);
  47. }
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. /**
  53. * 获取bean实例
  54. * @param beanName
  55. * @return
  56. */
  57. public Object getBean(String beanName) {
  58. return this.sigletons.get(beanName);
  59. }
  60. }

这样,传智播客版的Spring容器就创建出来了。接下来我们就要测试传智播客版的Spring容器是否能够取得bean实例,只须修改SpringTest类的代码为:

  1. public class SpringTest {
  2. @Test
  3. public void test() {
  4. // ApplicationContext是接口
  5. // ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 实例化Spring容器
  6. // PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
  7. // personService.save();
  8. ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml"); // 实例化Spring容器
  9. PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
  10. personService.save();
  11. }
  12. }

测试test()方法,Eclipse控制台打印如下: 
 
通过编写代码剖析Spring管理Bean的原理,我们就能深刻理解Spring内部到底是如何创建并管理bean实例的。源码可点击编码剖析Spring管理Bean的原理进行下载

(转)编码剖析Spring管理Bean的原理的更多相关文章

  1. Spring、编码剖析Spring管理Bean的原理

    引入dom4j jar包 1.新建Person接口和PersonBean public interface PersonIService { public void helloSpring(); } ...

  2. Spring第三弹—–编码剖析Spring管理Bean的原理

    先附一下编写的Spring容器的执行结果: 代码如下: 模拟的Spring容器类:   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  3. 编码剖析Spring管理bean的原理

    project目录 MyClassPathXMLApplicationContext读取xml,以及实例化bean. 因为是一开始实例化配置文件所有bean,所以需要构造器完成这些工作. packag ...

  4. (转)编码剖析Spring依赖注入的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...

  5. Spring、Spring依赖注入与编码剖析Spring依赖注入的原理

    Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...

  6. (转)编码剖析Spring装配基本属性的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52856465 上回我们已经讲到了Spring依赖注入的第一种方式,现在我们来详解第二种方式,须 ...

  7. (转)编码剖析@Resource注解的实现原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52860046 上文我们已经学会使用@Resource注解注入属性.学是学会了,但也仅限于会使用 ...

  8. 【Sping管理bean的原理】

    spring容器默认情况下,当服务启动时,解析配置文件,实例化文件中的所有类. 我们直接使用spring时,获取spring注入的bean是这样的, ApplicationContext ctx =  ...

  9. 采用Spring管理Bean和依赖注入

    1. 实例化spring容器和从容器获取Bean对象 实例化Spring容器常用的两种方式: 方法一: 在类路径下寻找配置文件来实例化容器 [推荐使用] ApplicationContext ctx ...

随机推荐

  1. 安装Sublime Text 3插件的方法(转自Rising的博文)

    安装Sublime Text 3插件的方法: 朋友们,小站活着不容易,全靠广告费养着了,如果本文对你有帮助.麻烦动下手点下页面的广告吧,谢谢! 直接安装 安装Sublime text 2插件很方便,可 ...

  2. 「 LuoguT37042」 求子序列个数

    Description 给定序列 A, 求出 A 中本质不同的子序列 (包含空的子序列) 个数模 10^9+ 7 的结果. 一个序列 B 是 A 的子序列需要满足 A 删掉某些元素后能够得到 B. 两 ...

  3. NOIP2007普及 守望者的逃离

    传送门 普及组的题目……很水. 原来写了一个模拟不过好像状态考虑的不全得了80,这次我们考虑一下dp做法. 守卫者有两种移动的方法,一种是闪现,一种是跑,我们可以把闪现和跑分开处理. 首先只处理闪现的 ...

  4. Memcached使用总结之:使用Python操作memcache

    Python连接memcached的库有很多,处于简单以及高效的原则,最终选择了pymemcache,优点完全实现了memcached text协议对于send/recv操作可以配置timeout支持 ...

  5. hadoop2 Ubuntu 下安装部署

    搭建Hadoop环境( 我以hadoop 2.7.3 为例, 系统为 64bit Ubuntu14.04 ) hadoop 2.7.3 官网下载 , 选择自己要安装的版本.注意每个版本对应两个下载选项 ...

  6. mysql5.7根据.frm和.ibd文件恢复表结构和数据

    一.恢复表结构 1.环境:Windows .mysql5.7:首先创建一个数据库,可以通过navicat来创建:     2.使用当前创建的数据库:use ww; 3.随意创建一张表,但是这张表的名字 ...

  7. 洛谷 - P5000 - Hillwer编码 - 高精度

    https://www.luogu.org/problemnew/show/P5000 第一次写一个正经的高精度题. 很明显ASCII码的乘积绝对是溢出的. 那么直接上Java.正好学一手Java的字 ...

  8. Educational Codeforces Round 21E selling souvenirs (dp)

    传送门 题意 给出n个体积为wi,价值为ci的物品,现在有一个m大的背包 问如何装使得最后背包内的物品价值最大,输出价值 分析 一般的思路是01背包,但n*v不可做 题解的思路 We can iter ...

  9. poj1837【背包】

    题意: 有一根杆子,给出一些杆子上的位置,位置上能放重物,再给出一些重物的重量. 重物都需要被使用,但是位置不一定都要用到. 问你能有多少种方法让这个杆子平衡. 思路: 在位置上是0/1背包思想,取或 ...

  10. hdoj2952【DFS联通块】

    我觉得还是这种不带回溯的直接搜到底的好玩啊!!!但是要注意边界,记得以前四周要空出来的一道题目,被坑了很久,还是wa到比赛结束!!!这道还是基础题 类似的基础题:POJ1562 hdoj1016 po ...