Spring IOC容器解析及实现原理
最近一段时间,“容器”两个字一直萦绕在我的耳边,甚至是吃饭、睡觉的时候都在我脑子里蹦来蹦去的。随着这些天一次次的交流、讨论,对于容器的理解也逐渐加深。理论上的东西终归要落实到实践,今天就借助spring容器实现原理,简单说说吧。
简单的说,Spring就是通过工厂+反射将我们的bean放到它的容器中的,当我们想用某个bean的时候,只需要调用getBean("beanID")方法。
原理简单介绍:
Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的bean,然后通过反射将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这些bean。下面是一段简单的模拟代码:
- package com.tgb.spring.factory;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.jdom.Document;
- import org.jdom.Element;
- import org.jdom.input.SAXBuilder;
- import org.jdom.xpath.XPath;
- public class ClassPathXmlApplicationContext implements BeanFactory {
- //容器的核心,用来存放注入的Bean
- private Map<String, Object> container = new HashMap<String, Object>();
- //解析xml文件,通过反射将配置的bean放到container中
- public ClassPathXmlApplicationContext(String fileName) throws Exception{
- SAXBuilder sb = new SAXBuilder();
- Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream(fileName));
- Element root = doc.getRootElement();
- List list = XPath.selectNodes(root, "/beans/bean");
- //扫描配置文件中的bean
- for (int i = 0; i < list.size(); i++) {
- Element bean = (Element) list.get(i);
- String id = bean.getAttributeValue("id");
- String clazz = bean.getAttributeValue("class");
- Object o = Class.forName(clazz).newInstance();
- container.put(id, o);
- }
- }
- @Override
- public Object getBean(String id) {
- return container.get(id);
- }
- }
首先声明一个存放bean的Map,然后通过jdom解析配置文件,循环遍历所有的<bean>节点,并通过反射将它们放到我们之前声明的Map中。然后提供一个getBean()的方法,让我们可以通过bean的Id来找到我们想要的bean。
下面是一个简单的xml配置文件:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans>
- <bean id="E" class="com.tgb.spring.factory.England" />
- <bean id="S" class="com.tgb.spring.factory.Spain" />
- <bean id="P" class="com.tgb.spring.factory.Portugal" />
- </beans>
客户端通过调用前面的ClassPathXmlApplicationContext,来加载上面的配置文件,然后就可以通过Id来获得我们需要的bean了:
- package com.tgb.spring.factory;
- public class Test {
- public static void main(String[] args) throws Exception {
- //加载配置文件
- BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml");
- //英格兰
- Object oe = f.getBean("E");
- Team e = (Team)oe;
- e.say();
- //西班牙
- Object os = f.getBean("S");
- Team s = (Team)os;
- s.say();
- //葡萄牙
- Object op = f.getBean("P");
- Team p = (Team)op;
- p.say();
- }
- }
输出结果:
- England :我们是欧洲的中国队,不在乎这次小组没出线...
- Spain :我们是两届欧洲杯冠军、一届世界杯冠军!
- Portugal:我们的C罗一个顶十个!
其他代码:
- //工厂接口
- package com.tgb.spring.factory;
- public interface BeanFactory {
- Object getBean(String id);
- }
- //Team接口
- package com.tgb.spring.factory;
- public interface Team {
- void say();
- }
- //英格兰
- package com.tgb.spring.factory;
- public class England implements Team{
- public void say() {
- System.out.println("England:我们是欧洲的中国队,不在乎这次小组没出线...");
- }
- }
- //西班牙
- package com.tgb.spring.factory;
- public class Spain implements Team{
- @Override
- public void say() {
- System.out.println("Spain:我们是两届欧洲杯冠军、一届世界杯冠军!");
- }
- }
- //葡萄牙
- package com.tgb.spring.factory;
- public class Portugal implements Team {
- @Override
- public void say() {
- System.out.println("Portugal:我们的C罗一个顶十个!");
- }
- }
以上内容是对Spring的一个简单模拟,当然Spring远比这个要复杂的多,也强大的多,而且获取bean的方式也不止通过工厂这一种。这里只是做一个粗略的Demo说说自己对容器的简单理解,向Spring致敬。例子简陋,表达粗糙,欢迎拍砖交流。
Spring IOC容器解析及实现原理的更多相关文章
- 【转】Spring学习---Spring IoC容器的核心原理
[原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...
- Spring IOC容器启动流程源码解析(四)——初始化单实例bean阶段
目录 1. 引言 2. 初始化bean的入口 3 尝试从当前容器及其父容器的缓存中获取bean 3.1 获取真正的beanName 3.2 尝试从当前容器的缓存中获取bean 3.3 从父容器中查找b ...
- Spring IOC容器启动流程源码解析(一)——容器概念详解及源码初探
目录 1. 前言 1.1 IOC容器到底是什么 1.2 BeanFactory和ApplicationContext的联系以及区别 1.3 解读IOC容器启动流程的意义 1.4 如何有效的阅读源码 2 ...
- Spring IOC容器的初始化-(二)BeanDefinition的载入和解析
前言 1.在讲BeanDefinition的载入和解析之前,我们先来看看什么是BeanDefinition. Bean对象在Spring中是以BeanDefinition来描述的,也就是说在Sprin ...
- Spring源码阅读-IoC容器解析
目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...
- Spring IOC容器的实现原理
1 概述 1.1 依赖反转模式 在Java中,一个复杂的功能一般都需要由两个或者两个以上的类通过彼此合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象的引用.如果这个获取依赖对象的过程需要自己去 ...
- spring-framework-中文文档一:IoC容器、介绍Spring IoC容器和bean
5. IoC容器 5.1介绍Spring IoC容器和bean 5.2容器概述 本章介绍Spring Framework实现控制反转(IoC)[1]原理.IoC也被称为依赖注入(DI).它是一个过程, ...
- Spring IOC 容器源码分析 - 填充属性到 bean 原始对象
1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...
- Spring IOC 容器源码分析 - 循环依赖的解决办法
1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...
随机推荐
- Hive group by实现-就是word 统计
准备数据 SELECT uid, SUM(COUNT) FROM logs GROUP BY uid; hive> SELECT * FROM logs; a 苹果 5 a 橙子 3 a 苹果 ...
- HANA aggregate 数字聚合
在project 1 里面 具有服务店代码,金额.应该上一层aggregate 就自动聚合了.可是并没有.要自己手工设置一下.在columns 右键变成——convert to aggregated ...
- Linux常用命令知识积累
基本操作 Linux关机,重启 # 关机 shutdown -h now # 重启 shutdown -r now 查看系统,CPU信息 # 查看系统内核信息 uname -a # 查看系统内核版本 ...
- power designer 设计数据库生成到oracle数据库
一.概念模型设计 1. 创建工程,创建概念设计模型,在快捷菜单栏调出 palette 找到表格工具,在主界面中创建表格. 2. 创建出的表格,双击进入设计模式 -------------------- ...
- bzoj3163 Eden的新背包问题
多重背包,$q$ 次询问,每次问删一个物品之后花费 $x$ 能装多少物品 $n \leq 3000, x \leq 1000, q \leq 300000$ sol: 网上有很多假做法 正解应该是考虑 ...
- POJ - 1324 Holedox Moving (状态压缩+BFS/A*)
题目链接 有一个n*m(1<=n,m<=20)的网格图,图中有k堵墙和有一条长度为L(L<=8)的蛇,蛇在移动的过程中不能碰到自己的身体.求蛇移动到点(1,1)所需的最小步数. 显然 ...
- Shell脚本备份Mongodb数据库
目录 环境还原 环境创建 编写shell脚本 准备文件 创建shell脚本 执行shell脚本 进阶版 感谢 诚邀访问我的个人博客:我在马路边 更好的阅读体验点击查看原文:Shell脚本备份Mongo ...
- 服务器上传大小限制 --- 来自 FastAdmin 项目开发的引发的问题 (TODO)
服务器上传大小限制 --- 来自 FastAdmin 项目开发的引发的问题 服务器上传有几个地方修改. FastAdmin 的配置. php.ini 的配置. NGINX 的配置.
- Vue 将样式绑定到一个对象让模板更清晰
Vue 将样式绑定到一个对象让模板更清晰 <div id="app"> <div v-bind:style="styleObject"> ...
- 在Azure New Portal上创建基于ARM的带SLB的VM
目前Azure的New Portal在国内已经上线了.本文将介绍最常见的一种场景:通过Azure的New Portal创建带有Server Load Balance的多台虚拟机. 1 创建Resour ...