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

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

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

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

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

dom4j读取到诸如

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

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

/**
* 将读取到的bean的信息存到一个JavaBean对象中
* @author li ayun
*
*/
public class BeanDefinition {
private String id;
private String className; public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}

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

/**
* 传智播客版Spring容器
* @author li ayun
*
*/
public class ItcastClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
private Map<String, Object> sigletons = new HashMap<String, Object>(); public ItcastClassPathXMLApplicationContext(String filename) {
this.readXML(filename);
this.instanceBeans();
} /**
* 完成bean的实例化
*/
private void instanceBeans() {
for (BeanDefinition beanDefinition : beanDefines) {
try {
if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())) {
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 读取XML配置文件
* @param filename
*/
private void readXML(String filename) {
SAXReader saxReader = new SAXReader();
Document document = null;
try {
URL xmlpath = this.getClass().getClassLoader().getResource(filename);
document = saxReader.read(xmlpath);
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans"); // 加入命名空间
XPath xsub = document.createXPath("//ns:beans/ns:bean"); // 创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap); // 设置命名空间
List<Element> beans = xsub.selectNodes(document); // 获取文档下所有bean节点
for (Element element : beans) {
String id = element.attributeValue("id"); // 获取id属性值
String clazz = element.attributeValue("class"); // 获取class属性值
BeanDefinition beanDefine = new BeanDefinition(id, clazz);
beanDefines.add(beanDefine);
}
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 获取bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName) {
return this.sigletons.get(beanName);
}
}

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

public class SpringTest {

    @Test
public void test() {
// ApplicationContext是接口
// ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); // 实例化Spring容器
// PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
// personService.save(); ItcastClassPathXMLApplicationContext ctx = new ItcastClassPathXMLApplicationContext("beans.xml"); // 实例化Spring容器
PersonService personService = (PersonService) ctx.getBean("personService"); // 从Spring容器取得bean
personService.save();
} }

测试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. 【AC自动机&&Trie图】积累

    以前KMP和后缀系列(主要是后缀数组,后缀自动机),都刷了一定数量的题,但是对于AC自动机,却有些冷落,罪过. 但是我感觉,在蓝桥杯比赛中AC自动机出现的概率比后缀系列大,简单的会考匹配,稍难一点会考 ...

  2. 通过HttpservletRequest对象获取客户端的真实IP地址

    这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...

  3. ES6 模板编译

    顾名思义,就是用反引号编写一个模板字符串, 用echo将模板转为javascrip表达式字符串, 用正则将基础字符串转为想要字符串 将代码封装在函数中返回: 注: 用到es6属性${} var tem ...

  4. 开发微信小程序心得

    元旦过后,根据公司的项目要求,项目组开始集体研究小程序,在这想谈点个人开发小程序心得,首先就是需要看小程序的文档,如同很多框架一样,不可能一上来就能动手敲代码(大神除外),其次就是不能一直单纯的看,因 ...

  5. 怎么在notepad里面,将字符串替换成换行

    用Notepad++可以,利用查找和替换功能,选择正则表达式,查找目标框里输入你想要替换的字符串,替换为框里输入\r,点击替换即可.这是个 很强大的功能,利用还它可以批量替换任何字符串,比如你链接是& ...

  6. lightoj 1031【区间DP,未完待续】

    题意: 给你一个n,再给你n个数,每个数<1e4; 有两个player交替取数字,每个人每一次能拿一个或多个,交替在两边拿. 游戏终止在所有的数字被取完. 两个人的分数就是所取得的数字大小总和. ...

  7. UVA1328 Period【KMP/周期串/循环节】By cellur925

    鲜有的在luogu发题解以及使用LaTex??? 就丢链接跑了.

  8. smtplib报警模块

    #!/usr/bin/env python # coding:utf-8 import time import subprocess import smtplib from email.mime.te ...

  9. Hdu 5452 Minimum Cut (2015 ACM/ICPC Asia Regional Shenyang Online) dfs + LCA

    题目链接: Hdu 5452 Minimum Cut 题目描述: 有一棵生成树,有n个点,给出m-n+1条边,截断一条生成树上的边后,再截断至少多少条边才能使图不连通, 问截断总边数? 解题思路: 因 ...

  10. mysql查询所有表名

    mysql使用sql查询表名的两种方法: 1.show tables; 2.SELECT TABLE_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WH ...