Tiny-Spring源码阅读(一)IOC的理解
Tiny-Spring作为spring一个简化版本,既包含了springIOC 与SpringAOP的主要部分,而且去除了其他不必要的成分,对于Spring的认识更加清晰,如果看Spring所有源码头大的话,可以看它。下面是我这几天对于TinySpring源码阅读的理解。特此记录。
一、什么是IOC?
IOC又叫做控制反转,过去生成代码需要手工new出来对象,使用IOC之后,可以将对象的创建交给Spring容器。这样很大程度上降低了耦合度。
二、IOC实现
(1) 对象的管理
Tiny-Spring对象的管理主要是通过BeanFactory,BeanFactory是一个接口,它只有一个方法getBean,用于对象的获取。
public interface BeanFactory {Object getBean(String name) throws Exception;
}
接下来是AbstractBeanFactory,作为IOC容器,它确定了一个容器的基本功能:
(1)将一个bean注册进容器中,bean的存储是通过哈希map实现。bean的id是键,值通过BeanDefinition存储,它包括了了对象的实例,className,Class,propertyValues。
(2)创建容器内的bean实例,它通过doCreateBean。并且AbstractBeanFactory将bean的创建分为两部分,实例化对象createBeanInstance以及加载对象的属性applyPropertyValues。并且,加载对象的属性交给子类实现,这样可以实现不同策略的加载方式。
另外,作为一个对象的属性property作为一个单独的类PropertyValue,这样更方便存储属性以及读取,而且一个对象所有的property保存在一个单独的类PropertyValues当中,而不是一个list,这样做是为了可以对propertyValue进行更多的操作,比如判重。另外需要注意:如果依赖的属性是另外一个类,那么它就是一个BeanReference,以此来区别普通属性。
然后定义了AutowireCapableBeanFactory,继承自AbstractBeanFactory,它作为一个自动装配的bean,在对象加载的时候自动完成属性的注入。这样一个基本的IOC容器就完成了。
测试代码:
AbstractBeanFactory abstractBeanFactory=new AutowireCapableBeanFactory();BeanDefinition beanDefinition=new BeanDefinition();beanDefinition.setBeanClassName("us.codecraft.tinyioc.context.Luck");abstractBeanFactory.registerBeanDefinition("luck", beanDefinition);Luck luck= (Luck) abstractBeanFactory.getBean("luck");luck.show();
(2)资源的加载
接下来,就需要考虑通过加载资源的方式加载属性了。首先,先考如何获取资源,tiny-spring定义了一个Resource接口,它只声明了一个方法,用于获取资源。
public interface Resource {InputStream getInputStream() throws IOException;}
然后就是具体的获取资源的方式了,tiny-spring只定义了URLResource获取资源,继承自Resource,当然也可以自己扩展。有了获取资源的方式,接下来需要考虑如何加载资源了,tiny-spring通过定义ResourceLoader类加载资源,它通过location获取资源路径,然后通过不同方式进行加载,单独这样定义一个类的目的是在有多种获取资源的方式的时候,减少了耦合度,但作者这个方法类我感觉不太妥当,getResource方法写死了。
(3)将资源载入容器中
有了加载资源的方式了,接下来的任务就是将资源加载到对象(BeanDefinition)中去了。Tiny-Spring提供了一个BeanDefinitionReader接口,以及它的抽象类AbstractBeanDefinitionReader,它的作用是获取ResourceLoader以及读取资源到beanDefinition对应的哈希map。然后是它的一个实现类XmlBeanDefinitionReader,它通过读取xml文件的方式将资源载入到哈希map中。
接下来任务就是将资源放入IOC容器中去了,这时候先使用ApplicationContext,它继承了BeanFactory,用于获取bean,然后是AbstractApplicationContext继承自ApplicationContext,它定义了加载资源方法refresh,以及加载策略onRefresh,表示在资源读取完成后立即将所有在容器中的对象实例化。同时,它还有一个抽象方法loadBeanDefinitions,表示资源载入容器中的方式。这个方法交给具体类实现,这里是ClassPathXmlApplicationContext,它的loadBeanDefinitions获取xml文件中的资源并将其放入容器中。然后就有了我们在Spring中常见的资源加载方式:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc-postbeanprocessor.xml");Hello helloWorldService = (Hello) applicationContext.getBean("show");helloWorldService.show();
三、总结
在Tiny-Spring IOC部分,用到的设计模式有,工厂模式,模板模式(定义了一个抽象类,类中一些方法交给子类来实现)。而且每一个类中的方法基本上符合单一职能原则,对于代码写的还比较差劲的人来说(比如我),真的有很大收获。代码虽然简洁,但是对于SpringIOC部分已经刻画的很详细了。
ps:渣渣一枚,如有不对请大佬指出。
转载于:https://www.cnblogs.com/GregZQ/p/8365269.html
Tiny-Spring源码阅读(一)IOC的理解相关推荐
- Spring源码阅读一——IOC
spring模块化设计: 接下来我会从最核心的模块开始阅读:Core Container 对应源码 Spring 3.2.X: http://docs.spring.io/spring/docs/3. ...
- 【Spring 源码阅读】Spring IoC、AOP 原理小总结
Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...
- 转 Spring源码剖析——核心IOC容器原理
Spring源码剖析--核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring 源码 ioc 编程 bean 更多 个人分类: Java https:// ...
- Spring源码阅读(一)——整体结构
Spring 总共大约有20个模块,由1300多个不同的文件构成. Spring源码阅读可以分为三个路线:IOC,AOP,外部组件. 个人主页:tuzhenyu's page 原文地址:Spring源 ...
- Spring源码阅读之bean对象的创建过程
Spring源码阅读之bean对象的创建过程 Spring是通过IOC容器来管理对象的,该容器不仅仅只是帮我们创建了对象那么简单,它负责了对象的整个生命周期-创建.装配.销毁.这种方式成为控制反转 ...
- spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor
接着上文<spring源码阅读(2)-- 容器启动之加载BeanDefinition>,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置bean ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- spring源码深度解析— IOC 之 默认标签解析(下)
默认标签中的自定义标签解析 注册解析的BeanDefinition 通过beanName注册BeanDefinition 通过别名注册BeanDefinition alias标签的解析 import标 ...
- Spring 源码总结、IOC、循环依赖、AOP分析
Spring 源码 本文基于 jdk 11 核心类 interface BeanFactory 该接口是访问 Spring bean 容器的根接口,是 bean 容器的基本客户端视图: 其他接口如Li ...
- Spring源码阅读 源码环境搭建(一)
ring 源码阅读的搭建(一) 一 下载spring源码 进入官方网页:https://spring.io/projects/spring-framework 进入相关的github位置,下载zip包 ...
最新文章
- 不同视图间的跳转方式
- 创建存储,修改存储_安全地创建和存储密码
- 十一、CSS初始化详解
- 2017 4月20日下午
- mysql 5.7 error log_MySQL · 特性分析 · 5.7 error log 时区和系统时区不同
- python函数 range()和arange()
- 直播网站源码,输入框中显示小图标
- 数据结构(C语言版本)
- 最简单DIY基于STM32F407探索者开发板的MPU6050陀螺仪姿态控制舵机程序
- ios正式包ipa,发布苹果应用商店App Store
- tomcat修改主页
- 赛码-回文串-java
- 微分方程建模实例:对药剂量开处方
- 黑马主播单场带货千万,抖音直播市场还有哪些新机遇?
- 退出计算机用户的快捷方式,如何注销计算机或从Windows 10注销
- 锤子手机便签导入另一个手机云便签中怎么操作?
- java并发编程第二课 线程锁和线程安全
- Elasticsearch语法知多少之Multi_match query
- fine ui grid控件添加行号
- 韩顺平 2022零基础学 Java 学习笔记(1)
热门文章
- hibernate DetachedCriteria实现多表关联查询createAlias的使用
- Linux内核中的jiffies及其作用介绍及jiffies等相关函数详解
- WEB前端开发书籍推荐
- Ubuntu Linux 8.04 Vsftp 假造用户设置
- 校园网打开IEEE 显示未登录
- Tests for normality正态分布检验
- reporting server 数据头部每页显示
- 伪静态在webconfig中配置
- Windows下C++计算代码段运行时间
- Sitecore8.2 GeoIP - 在8.2的引擎盖下发生了什么?