最近一段时间,“容器”两个字一直萦绕在我的耳边,甚至是吃饭、睡觉的时候都在我脑子里蹦来蹦去的。随着这些天一次次的交流、讨论,对于容器的理解也逐渐加深。理论上的东西终归要落实到实践,今天就借助spring容器实现原理,简单说说吧。

简单的说,Spring就是通过工厂+反射将我们的bean放到它的容器中的,当我们想用某个bean的时候,只需要调用getBean("beanID")方法。

原理简单介绍:

Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的bean,然后通过反射将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这些bean。下面是一段简单的模拟代码:

  1. package com.tgb.spring.factory;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import java.util.Map;
  5. import org.jdom.Document;
  6. import org.jdom.Element;
  7. import org.jdom.input.SAXBuilder;
  8. import org.jdom.xpath.XPath;
  9. public class ClassPathXmlApplicationContext implements BeanFactory  {
  10. //容器的核心,用来存放注入的Bean
  11. private Map<String, Object> container = new HashMap<String, Object>();
  12. //解析xml文件,通过反射将配置的bean放到container中
  13. public ClassPathXmlApplicationContext(String fileName) throws Exception{
  14. SAXBuilder sb = new SAXBuilder();
  15. Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream(fileName));
  16. Element root = doc.getRootElement();
  17. List list = XPath.selectNodes(root, "/beans/bean");
  18. //扫描配置文件中的bean
  19. for (int i = 0; i < list.size(); i++) {
  20. Element bean = (Element) list.get(i);
  21. String id = bean.getAttributeValue("id");
  22. String clazz = bean.getAttributeValue("class");
  23. Object o = Class.forName(clazz).newInstance();
  24. container.put(id, o);
  25. }
  26. }
  27. @Override
  28. public Object getBean(String id) {
  29. return container.get(id);
  30. }
  31. }

首先声明一个存放bean的Map,然后通过jdom解析配置文件,循环遍历所有的<bean>节点,并通过反射将它们放到我们之前声明的Map中。然后提供一个getBean()的方法,让我们可以通过bean的Id来找到我们想要的bean。

下面是一个简单的xml配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans>
  3. <bean id="E" class="com.tgb.spring.factory.England" />
  4. <bean id="S" class="com.tgb.spring.factory.Spain" />
  5. <bean id="P" class="com.tgb.spring.factory.Portugal" />
  6. </beans>

客户端通过调用前面的ClassPathXmlApplicationContext,来加载上面的配置文件,然后就可以通过Id来获得我们需要的bean了:

  1. package com.tgb.spring.factory;
  2. public class Test {
  3. public static void main(String[] args) throws Exception {
  4. //加载配置文件
  5. BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml");
  6. //英格兰
  7. Object oe = f.getBean("E");
  8. Team e = (Team)oe;
  9. e.say();
  10. //西班牙
  11. Object os = f.getBean("S");
  12. Team s = (Team)os;
  13. s.say();
  14. //葡萄牙
  15. Object op = f.getBean("P");
  16. Team p = (Team)op;
  17. p.say();
  18. }
  19. }

输出结果:

  1. England :我们是欧洲的中国队,不在乎这次小组没出线...
  2. Spain   :我们是两届欧洲杯冠军、一届世界杯冠军!
  3. Portugal:我们的C罗一个顶十个!

其他代码:

  1. //工厂接口
  2. package com.tgb.spring.factory;
  3. public interface BeanFactory {
  4. Object getBean(String id);
  5. }
  6. //Team接口
  7. package com.tgb.spring.factory;
  8. public interface Team {
  9. void say();
  10. }
  11. //英格兰
  12. package com.tgb.spring.factory;
  13. public class England implements Team{
  14. public void say() {
  15. System.out.println("England:我们是欧洲的中国队,不在乎这次小组没出线...");
  16. }
  17. }
  18. //西班牙
  19. package com.tgb.spring.factory;
  20. public class Spain implements Team{
  21. @Override
  22. public void say() {
  23. System.out.println("Spain:我们是两届欧洲杯冠军、一届世界杯冠军!");
  24. }
  25. }
  26. //葡萄牙
  27. package com.tgb.spring.factory;
  28. public class Portugal implements Team {
  29. @Override
  30. public void say() {
  31. System.out.println("Portugal:我们的C罗一个顶十个!");
  32. }
  33. }

以上内容是对Spring的一个简单模拟,当然Spring远比这个要复杂的多,也强大的多,而且获取bean的方式也不止通过工厂这一种。这里只是做一个粗略的Demo说说自己对容器的简单理解,向Spring致敬。例子简陋,表达粗糙,欢迎拍砖交流。

Spring IOC容器解析及实现原理的更多相关文章

  1. 【转】Spring学习---Spring IoC容器的核心原理

    [原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...

  2. Spring IOC容器启动流程源码解析(四)——初始化单实例bean阶段

    目录 1. 引言 2. 初始化bean的入口 3 尝试从当前容器及其父容器的缓存中获取bean 3.1 获取真正的beanName 3.2 尝试从当前容器的缓存中获取bean 3.3 从父容器中查找b ...

  3. Spring IOC容器启动流程源码解析(一)——容器概念详解及源码初探

    目录 1. 前言 1.1 IOC容器到底是什么 1.2 BeanFactory和ApplicationContext的联系以及区别 1.3 解读IOC容器启动流程的意义 1.4 如何有效的阅读源码 2 ...

  4. Spring IOC容器的初始化-(二)BeanDefinition的载入和解析

    前言 1.在讲BeanDefinition的载入和解析之前,我们先来看看什么是BeanDefinition. Bean对象在Spring中是以BeanDefinition来描述的,也就是说在Sprin ...

  5. Spring源码阅读-IoC容器解析

    目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...

  6. Spring IOC容器的实现原理

    1 概述 1.1 依赖反转模式 在Java中,一个复杂的功能一般都需要由两个或者两个以上的类通过彼此合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象的引用.如果这个获取依赖对象的过程需要自己去 ...

  7. spring-framework-中文文档一:IoC容器、介绍Spring IoC容器和bean

    5. IoC容器 5.1介绍Spring IoC容器和bean 5.2容器概述 本章介绍Spring Framework实现控制反转(IoC)[1]原理.IoC也被称为依赖注入(DI).它是一个过程, ...

  8. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  9. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

随机推荐

  1. Django pymysql学员管理系统

    学员管理系统 项目规划阶段 项目背景 近年来老男孩教育的入学学员数量稳步快速增长,传统的excel统计管理学员信息的方式已经无法满足日渐增长的业务需求.因此公司急需一套方便易用的“学员管理系统”,来提 ...

  2. 2018.7.30 Designing a Qi-compliant receiver coil for wireless power systems

    1) 找资料: http://www.mouser.cn/datasheet/2/389/stwlc33-1156583.pdf https://training.ti.com/wireless-po ...

  3. (转)关于Linux核心转储文件 core dump

    所谓核心转储文件是内含进程终止时内存映像的一个文件.产生条件:特定的信号会引发进程创建一个核心转储文件并终止运行. 包括哪些特定信号,请参见http://man7.org/linux/man-page ...

  4. Ajax做日期选择

    1.主页面 引入JS Jquery bootstrap 包 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...

  5. 使用visio 2010建立sql server数据模型——手动画、利用逆向工程

    基础数据库这个词不在新鲜,老早就提出了.咱们从出生,个人信息就被放到一个基本信息库中了,在全国各地,通过身份证号就能知道你的基本信息.最近米老师 下发了一个任务,让我们开发几个小项目,考试系统.选修课 ...

  6. BZOJ - 3631 松鼠的新家 (树链剖分)

    题目链接 树链剖分基础题,路径权值修改+差分 #include<bits/stdc++.h> using namespace std; typedef long long ll; ; in ...

  7. 「BZOJ2510」弱题(矩阵乘法,降维)

    有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M),若这个球标号为k(k < ...

  8. 一文搞定 Git 相关概念和常用指令

    我几乎每天都使用 Git,但仍然无法记住很多命令. 通常,只需要记住下图中的 6 个命令就足以供日常使用.但是,为了确保使用地很顺滑,其实你应该记住 60 到 100 个命令. Git 相关术语 Gi ...

  9. jacksi(比较实用的工具批处理)

    批处理类别: 国产软件 批处理语言: 简体中文 授权方式: 免费软件 运行环境: Windows平台 警告:运行BAT源码是一种危险的动作,如果你不熟悉,请不要尝试! 这里分享的是用bat写的比较实用 ...

  10. git-SSH连接配置

    1.1 在电脑端生成sshkey文件 打开git bash 输入: ssh-keygen -t rsa -C "xxxxxxx邮箱地址" 期间要输入两次密码[github远程添加s ...