spring源码分析第三天------spring核心IOC容器和依赖注入原理
基于XML的依赖注入
1、依赖注入发生的时间
当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后,IOC 容器中已经管理类 Bean 定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入,依赖注入在以下两种情况 发生:
(1).用户第一次通过 getBean 方法向 IOC 容索要 Bean 时,IOC 容器触发依赖注入。
(2).当用户在 Bean 定义资源中为元素配置了 lazy-init 属性,即让容器在解析注册 Bean 定义 时进行预实例化,触发依赖注入
BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和 最基本的编程规范。BeanFactory 接口中定义了几个 getBean 方法,就是用户向 IOC 容器索取管理的 Bean 的方法。
在 BeanFactory 中我们看到 getBean(String…)函数,它的具体实现在 AbstractBeanFactory 中。
2、AbstractBeanFactory 通过 getBean 向 IOC 容器获取被管理的 Bean,
在 Spring 中,如果 Bean 定义的单例模式 (Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果 Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean 定义还可 以扩展为指定其生命周期范围。
3、具体的依赖注入实现在以下两个方法中:
(1).createBeanInstance:生成 Bean 所包含的 java 对象实例。
(2).populateBean :对 Bean 属性的依赖注入进行处理
详细可以从我的GitHub下载源码进行学习,对关键步骤我都有进行注释。如果对您有帮助,麻烦三连,您的支持,是我进行原创最大的动力!
额外信息补充:
定位:资源配置和定位,包括import、classpath、url;
加载:解析配置文件,把bean包装为beanDefinition对象,BeanDefinition 相当于是保存在内存中的配置文件,保存了所有的跟类属性相关信息;
注册:把已经初始化的BeanDefinition对象放入到IOC容器中;
依赖注入DI,就是把BeanDefinition中的信息读取出来,利用反射机制,或者代理机制创建对象,新创建的对象,不会放到我们印象中的IOC容器中,它存入到另外一个cache容器;
减少代码侵入,能够在原生的基础之上,再进行扩展,监听器、回调函数、标记信息;
原生 Bean: 通过反射或者代理机制创建的Bean;
BeanWrapper: 是原生Bean的包装,通过构造方法实现包装,真正操作的是Wrapper,放入cache的只是Wrapper;
FacoryBean:是Spring中最顶层接口,只要是通过工厂创建Bean,都要实现FacotryBean;
parseBeanDefinitions 方法实际是解析xml,把xml中的内容变成BeanDefinition;
补充一些IOC一些其他高级特性
1、如使用 lazy-init 属性对 Bean 预初始化;
2、FactoryBean 产生或 者修饰 Bean 对象的生成;
3、IOC 容器初始化 Bean 过程中使用 BeanPostProcessor 后置处理器对 Bean 声明周期事件管理;
4、IOC 容器的 autowiring 自动装配功能等;
1、Spring IOC 容器的 lazy-init 属性实现预实例化:
通过前面我们对 IOC 容器的实现和工作原理分析,我们知道 IOC 容器的初始化过程就是对 Bean 定 义资源的定位、载入和注册,此时容器对 Bean 的依赖注入并没有发生,依赖注入主要是在应用程序第 一次向容器索取 Bean 时,通过 getBean 方法的调用完成。 当Bean定义资源的元素中配置了lazy-init属性时,容器将会在初始化的时候对所配置的Bean 进行预实例化,Bean 的依赖注入在容器初始化的时候就已经完成。
2、FactoryBean和BeanFactory的区别
BeanFactory主语是factory,具体工厂会通过策略模式去实现,不同的工厂生成不同的产品;
FacoryBean:是Spring中最顶层接口,只要是通过工厂创建Bean,都要实现FacotryBean;
BeanFactory生产的产品都是FacoryBean
大部分情况下,BeanFactory本身也是由BeanFactory创建的,也就是说BeanFactory也是FactoryBean
spring中所有的bean都是FactoryBean。
3、BeanPostProcessor 后置处理器的实现:
BeanPostProcessor 后置处理器是 Spring IOC 容器经常使用到的一个特性,这个 Bean 后置处理器是 一个监听器,可以监听容器触发的 Bean 声明周期事件。后置处理器向容器注册以后,容器中管理的 Bean 就具备了接收 IOC 容器事件回调的能力。
4、Spring IOC 容器 autowiring 实现原理:
Spring IOC 容器提供了两种管理 Bean 依赖关系的方式:
a.显式管理:通过 BeanDefinition 的属性值和构造方法实现 Bean 依赖关系管理。
b.autowiring:Spring IOC 容器的依赖自动装配功能,不需要对 Bean 属性的依赖关系做显式的声明, 只需要在配置好 autowiring 属性,IOC 容器会自动使用反射查找属性的类型和名称,然后基于属性的 类型或者名称来自动匹配容器中管理的 Bean,从而自动地完成依赖注入。
通过对 autowiring 自动装配特性的理解,我们知道容器对 Bean 的自动装配发生在容器对 Bean 依赖 注入的过程中。在前面对 Spring IOC 容器的依赖注入过程源码分析中,我们已经知道了容器对 Bean 实例对象的属性注入的处理发生在 AbstractAutoWireCapableBeanFactory 类中的 populateBean 方法中。
autowiring 的实现过程:
a.对 Bean 的属性代调用 getBean 方法,完成依赖 Bean 的初始化和依赖注入。
b.将依赖 Bean 的属性引用设置到被依赖的 Bean 属性上。
c.将依赖 Bean 的名称和被依赖 Bean 的名称存储在 IOC 容器的集合中。
Spring IOC 容器的 autowiring 属性自动依赖注入是一个很方便的特性,可以简化开发时的配置,但 是凡是都有两面性,自动属性依赖注入也有不足,首先,Bean 的依赖关系在配置文件中无法很清楚地 看出来,对于维护造成一定困难。其次,由于自动依赖注入是 **Spring 容器自动执行的,容器是不会智 能判断的,**如果配置不当,将会带来无法预料的后果,所以自动依赖注入特性在使用时还是综合考虑。
spring源码分析第三天------spring核心IOC容器和依赖注入原理相关推荐
- spring源码分析第五天------springAOP核心原理及源码分析
spring源码分析第五天------springAOP核心原理及源码分析 1. 面向切面编程.可以通过预 编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 切面(A ...
- spring源码分析第四天------springmvc核心原理及源码分析
spring源码分析第四天------springmvc核心原理及源码分析 1.基础知识普及 2. SpringMVC请求流程 3.SpringMVC代码流程 4.springMVC源码分析 4.1 ...
- spring源码分析01-(前期准备)spring核心原理解析和手写简易spring
1.本文主要介绍内容 本文会把Spring中核心知识点大概解释下.可以对Spring的底层有一个整体的大致了解.主要内容包括: 手写简易spring框架,帮助更好理解spring. 代码点击链接自取 ...
- Spring源码分析【4】-Spring扫描basePackages注解
org.springframework.beans.factory.support.DefaultListableBeanFactory 重要数据结构 /** Map of bean definiti ...
- Spring源码分析【7】-Spring 模板页和JSP文件的编译
org.apache.jasper.servlet.JspServletWrapper.service org.apache.jasper.JspCompilationContext.compile ...
- Spring源码分析【5】-Spring MVC处理流程
org.apache.catalina.core.ApplicationFilterChain.doFilter 获取Filter org.apache.catalina.core.Applicati ...
- Spring源码分析(三)
Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring 源码分析衍生篇十 :Last-Modified 缓存机制
文章目录 一.前言 二.Last-Modify 三.实现方案 1. 实现 org.springframework.web.servlet.mvc.LastModified接口 1.1. 简单演示 1. ...
最新文章
- MySQL/phpmyadmin问题解决手记:#2002 – 服务器没有响应 (或者本地 MySQL 服务器的套接字没有正确配置)
- Python的浅拷贝和深拷贝
- python怎么跳转到某一行代码_Python中免验证跳转到内容页的实例代码
- Angular之ngx-permissions的管理权限
- pix2pix笔记(B站,更加清晰)
- GitGithub学习笔记
- less+rem迭代适配
- Tcl Tutorial 笔记8 · proc
- USACO stamps
- Bootstrap自定义图标
- 河北省教育厅计算机制度,河北省中小学计算机室规章制度.doc.docx
- Emacs快捷键 转自:http://www.engr.uvic.ca/~dastone/emacs-keys.html
- 如何通过交互设计增强用户体验
- uni-app使用canvas将两张图片合成一张图片
- UE4 角色上下车功能
- Mac快捷键大全及cheatsheet插件
- 想要搭建建基于Nodejs的网站怎么做
- redis实现“附近的人”
- JavaWeb源码项目蔬菜网上商城+后台管理系统
- iPhone字体显示大全
热门文章
- stl向量_如何在C ++ STL中将数组元素复制到向量?
- webstorm使用技巧
- 水印生成器第2版[原图质量水印可自定义设置]
- 常量指针与指针常量勘误
- mybatis进行CRUD操作时返回值不为影响的条数,为null
- mysql phpmyadmin远程_phpmyadmin登录远程mysql数据库
- alxctools索引超出了数组界限_[译]V8中的数组类型
- linux安装python27_linux下安装python27 nginx 和uwsgi
- gsm模块网站服务器,gsm模块是什么_gsm模块工作原理_gsm模块的应用
- 光滑噪声数据常用的方法_数据挖掘中常用的数据清洗方法