spring的IOC容器能够帮我们自动new对象,对象交给spring管之后我们不用自己手动去new对象了。那么它的原理是什么呢?是怎么实现的呢?下面我来简单的模拟一下spring的机制,相信看完之后就会对spring的原理有一定的了解。

  spring使用BeanFactory来实例化、配置和管理对象,但是它只是一个接口,里面有一个getBean()方法。我们一般都不直接用BeanFactory,而是用它的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map中,键就是我们bean的id,值就是new的对象。

  首先我们建立一个BeanFactory接口

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

  然后建立一个BeanFactory的实现类ClassPathXmlApplicationContext.java

 1 package com.spring;
2
3 import java.util.HashMap;
4 import java.util.List;
5 import java.util.Map;
6
7 import org.dom4j.Document;
8 import org.dom4j.DocumentException;
9 import org.dom4j.Element;
10 import org.dom4j.io.SAXReader;
11
12
13 public class ClassPathXmlApplicationContext implements BeanFactory {
14 private Map<String, Object> beans = new HashMap<String, Object>();
15 public ClassPathXmlApplicationContext(String fileName) throws Exception{
16 SAXReader reader = new SAXReader();
17 Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));
18 List<Element> elements = document.selectNodes("/beans/bean");
19 for (Element e : elements) {
20 String id = e.attributeValue("id");
21 String value = e.attributeValue("class");
22 Object o = Class.forName(value).newInstance();
23 beans.put(id, o);
24 }
25 }
26
27 public Object getBean(String id) {
28 return beans.get(id);
29 }
30
31 }

  然后配置applicationContext.xml

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans>
3 <bean id="c" class="com.spring.Car"></bean>
4 <bean id="p" class="com.spring.Plane"></bean>
5 </beans>

创建类的时候顺便演示一下工厂模式,其实BeanFactory它也是一种工厂模式的。

1 package com.spring;
2
3 public interface Moveable {
4 void run();
5 }
1 package com.spring;
2
3 public class Car implements Moveable{
4
5 public void run(){
6 System.out.println("拖着四个轮子满街跑car·····");
7 }
8 }
1 package com.spring;
2
3 public class Plane implements Moveable{
4
5 public void run() {
6 System.out.println("拖着翅膀天空飞plane......");
7 }
8
9 }

现在来看一看效果吧,写一个类测试一下:

 1 package com.spring;
2
3 import org.dom4j.DocumentException;
4
5 public class Test {
6
7 /**
8 * @param args
9 * @throws DocumentException
10 */
11 public static void main(String[] args) throws Exception {
12 BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
13 Object o = factory.getBean("c");
14 Moveable m = (Moveable)o;
15 m.run();
16 }
17
18 }

由于Map容器里面保存的是Object类型,所以通过getBean()方法取出来的对象要强制类型转换。

Spring源码学习之:模拟实现BeanFactory,从而说明IOC容器的大致原理的更多相关文章

  1. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  2. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  3. Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作

    写在前面 上文 Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件主要讲Spring容器创建时通过XmlBeanDefinitionReader读 ...

  4. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  5. Spring 源码学习——Aop

    Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ...

  6. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  7. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

  8. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  9. Spring 源码学习 04:初始化容器与 DefaultListableBeanFactory

    前言 在前一篇文章:创建 IoC 容器的几种方式中,介绍了四种方式,这里以 AnnotationConfigApplicationContext 为例,跟进代码,看看 IoC 的启动流程. 入口 从 ...

  10. Spring源码学习笔记9——构造器注入及其循环依赖

    Spring源码学习笔记9--构造器注入及其循环依赖 一丶前言 前面我们分析了spring基于字段的和基于set方法注入的原理,但是没有分析第二常用的注入方式(构造器注入)(第一常用字段注入),并且在 ...

随机推荐

  1. hive内部表、外部表

    hive内部表.外部表区别自不用说,可实际用的时候还是要小心. Hive的数据分为表数据和元数据,表数据是Hive中表格(table)具有的数据:而元数据是用来存储表的名字,表的列和分区及其属性,表的 ...

  2. Html获取经纬度

    if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function success(pos) {alert( ...

  3. HTML--11marquee标签

    页面的自动滚动效果,可由javascript来实现, 但是有一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 使用marquee ...

  4. lightoj1080 线段树

    //Accepted 6628 KB 520 ms //I a b 把a到b区间的二进制位去反,转化成a到b区间的数全部加1 //Q a 判断第a位的奇偶 #include <cstdio> ...

  5. poj1125(Floyd最短路)

    //Accepted 164 KB 0 ms //floyd #include <cstdio> #include <cstring> #include <iostrea ...

  6. php大力力 [004节]PHP常量MAMP环境下加载网页

    我的问题是:“让mamp加载PHP文件”. 这个特别简单的问题,刚才也把我憋了几个钟头,唉....土啊,新学一个东西,学习成本就是高. 刚刚吃了好吃的南邵小龙虾,以及美味的八里桥大螃蟹,痛苦了半天,终 ...

  7. 考古备份:a.out文件ELF文件头中魔数的由来

    来源: <程序员的自我修养>3.4节. 补充: http://wiki.osdev.org/ELF http://www.linux-mag.com/id/116/ http://en.w ...

  8. 【LeetCode OJ】Populating Next Right Pointers in Each Node II

    Problem Link: http://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ OK... ...

  9. HDU 1695

    http://acm.hdu.edu.cn/showproblem.php?pid=1695 x是[1,b],y是[1,d],求GCD(x,y)=k的对数(x,y无序) 对x,y都除以k,则求GCD( ...

  10. magento的robots文件编写和判断是否是一个导航分类页面

    magento是网店系统,我们突出的是我们的产品,所以,有很多路径我们不想让搜索引擎索引到,所以我们需要用robots文件进行限制 下面是麦神magento的robots.txt里面的内容,因为很多u ...