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 容器自动执行的,容器是不会智 能判断的,**如果配置不当,将会带来无法预料的后果,所以自动依赖注入特性在使用时还是综合考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558799.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb中监听器Listener+过滤器filter+拦截器interceptor区别

JavaWeb中监听器Listener过滤器filter拦截器interceptor区别 如果从整个项目中看,一个servlet请求的执行过程就变成了这样context-param–>listener–>filter–>servlet–>interceptor(指的是拦截器) 1.概念 context-param:就是一些需要初…

Linux进阶之路————开机、重启和用户登录注销

关机、重启命令 shutdown 命令: 1)shutdown -h now 立即关机 2)shutdown -h 1 1分钟之后关机 3)shutdown -r now 立即重启 reboot 命令,直接使用,表示立即重启 halt 命令&am…

spring源码分析第四天------springmvc核心原理及源码分析

spring源码分析第四天------springmvc核心原理及源码分析 1、基础知识普及 2、 SpringMVC请求流程 3、SpringMVC代码流程 4、springMVC源码分析 4.1 4.2 4.3 5、Spring MVC 的优化 补充: SpringMVC经典设计是handlerMapping,大家可以看一…

Linux进阶之路————用户管理

引言 前面几篇关于Linux的已经大概领略了Linux的风采,本篇用户管理,将着重总结日常工作中,非常重要的用户管理功能。 主要包括:新增用户、删除用户、查询用户信息、指定/修改密码、切换用户、用户组,以及与用户管理相…

spring源码分析第五天------springAOP核心原理及源码分析

spring源码分析第五天------springAOP核心原理及源码分析 1、 面向切面编程。可以通过预 编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术 切面(Aspect) 连接点(Joinpoint) 通知&#x…

Linux进阶之路————Linux运行级别(重置密码)

引言 前面的《Linux进阶之路————开机、重启和用户登录注销》已经简单介绍过Linux系统运行级别的概念,今天来详细介绍和总结一下Linux的运行级别。 inittab配置文件 在配置文件目录下有一个inittab文件/etc/inittab,用于专门存储系统的运行级别&am…

Linux问题处理————命令提示符显示 bash-4.1# 解决方案

引言 本文系Linux学习过程中的一个小插曲。 在使用root用户创建了一个普通的tom 用户之后,系统莫名其妙卡死,重启后,发现命令提示符不再是 “用户名 目录”这种组合,而变成了 bash-4.1# 开头: 解决办法 将/etc/ske…

spring源码分析第六天------spring经典面试问题

spring源码分析第六天------spring经典面试问题 1、Spring5 新特性及应用举例 2、Spring 经典的面试问题 a、什么是 Spring 框架?Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发提供了综合、广泛的基础性支持的 Java 平台。Spr…

Linux进阶之路————scp指令介绍与演示

引言 目前市场上很多终端软件都自带文件传输功能,且多为图形化界面,操作简单无脑。但是本着“指令最高端,拖拽贼JBLow”的原则,今天学习一下文件传输的命令:scp 操作演示 准备两台linux服务器 (我的是弄…

Mybatis源码分析第一天------Mybatis实用篇

Mybatis源码分析第一天------Mybatis实用篇 一切最基本的操作就是参考官方文档:https://mybatis.org/mybatis-3/zh/configuration.html 1、是什么 什么是 MyBatis? a、MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级…

深入理解Tomcat和Jetty源码之第一篇前奏知识

深入理解Tomcat和Jetty源码之第一篇前奏知识 这周开始对Tomcat和Jetty的源码和框架产生了浓厚的兴趣,接下来想记录一下学习Tomcat和Jetty源码的心得和体会,有兴趣的朋友可以关注一下,我主要以思维导图的方式来展现整体的学习思路~ 今天的整体…

Linux进阶之路————组管理与权限管理

引言 这篇博客将会总结一些关于组的概念和相关操作,以及文件的一些权限管理。 一、组的基本介绍 在前面的博文《Linux进阶之路————用户管理》已经有提到用户组的概念,实际上,组的概念并不局限于用户,文件和目录都有组的概念…

深入理解Tomcat和Jetty源码之第二篇servlet规范和servlet容器

深入理解Tomcat和Jetty源码之第二篇servlet规范和servlet容器 思维导图总览 这篇推送主要讲servlet的规范和什么是servlet容器? 1、先来讲讲servlet规范: 2、再用一个图来说明一下servlet容器是如何工作的 3、web应用 4、本节的重点,filter和…

JavaScript————FormData实现多文件上传

引言 星期四的时候,我遇到了一个文件上传的问题,与以往不同的是,这一次上传的是多个文件,而且涉及到了久违的javascript代码。 虽然最后实现的并不尽如人意,不过也算是完成了功能,接下来就把我发现的一些问…

深入理解Tomcat和Jetty源码之第三篇tomcat系统架构上:连接器是如何设计的

我们都知道Tomcat服务器是包括连接器和容器,​那他们内部具体是怎么实现的呢?今天让我们一起来学习一下~ 1、tomcat基础知识 2、tomcat和service的关系 3、tomcat的详细介绍(重点) 3.1、连接器 3.1.1、ProtocolHandler组件 3.1.2、…

Maven学习(一)————Maven技术概述

引言 在过去的项目开发中,存在很多实操性的痛点: 1、一个项目只通过一个巨大的java工程来开发,随着模块的增多,工程也变得异常庞大,不利于分工和管理。 2、过去需要的第三方 api 接口需要通过手动导包的形式&#x…

深入理解Tomcat和Jetty源码之第四篇tomcat系统架构上:容器是如何设计的

今天来介绍一下Tomcat的容器机制: 1、Tomcat的四种容器 2、容器示意图 3、责任链模式介绍 4、Tomcat如何确定请求是哪个Wrapper处理的 5、Tomcat的Context和servlet的ServletContext还有Spring的ApplicationContext有什么不同

Maven学习(二)————Maven核心概念(一)

引言 Maven 作为项目构建工具,学习成本并不大,但是如果搞不懂它的一些核心概念,使用起来还是不能特别得心应手。 Maven的核心概念包括以下这些: 1、约定的目录结构 2、POM 3、坐标 4、依赖 5、仓库 6、生命周期/插件/目…

Maven学习(三)————Maven核心概念(二)

引言 承接上一篇《Maven学习(二)————Maven核心概念(一)》,介绍 Maven 生命周期、插件、目标、继承、聚合等一些概念。 一、Maven 生命周期 1.1 理解 Maven 生命周期及主要构建过程 Maven 构建生命周期&#x…

Maven学习(四)————Eclipse 中的 Maven 工程

引言 创建一个 Maven 版 Hello World。 一、Eclipse 中 Maven 插件的准备工作 除了 JDK 和必须的 Eclipse 之外,还需要在 Eclipse 中设置Maven 相关的信息。这里有最重要的两项 maven 配置: 1.1 Maven Installations 说明:该项设置是指定…