spring底层分析(bean的加载流程)

文章详细解析了Spring框架中Bean的加载流程,从通过AbstractBeanFactory的doGetBean方法开始,涉及beanName的解析、缓存检查、FactoryBean处理、单例bean创建、构造及初始化过程,以及循环依赖检测和销毁方法注册。整个过程展示了Spring如何管理和实例化Bean。
摘要由CSDN通过智能技术生成

spring的bean的加载,说得通俗一点,就是我们通过spring容器,获取到我们想要的bean,而在这个获取过程,spring 做的事情,就是bean的加载;这里我推荐一篇博客,我是通过这篇博客,解决了我的很多疑问Spring源码解析:Bean的加载流程_spring的bean加载过程_所遇皆惊喜的博客-CSDN博客

1. 同样,我们先自己搭建一个spring环境,调用IOC容器的getBean()方法

进入AbstractBeanFactory中的doGetBean方法

2. doGetBean方法

进入到doGetBean方法后,在这里可以大致分为两步,一步是可以直接从缓存中获取到的bean,另一步是不能从缓存中的bean(这里概述可能不是特别准确,建议真心想了解的读者,下来可以真正的更多的通过相应的书籍进行了解)

2.1 这里先了解直接从缓存中就能获取到的bean

进来之后无论是从缓存中获取Bean还是创建bean,都调用了transformedBeanName(name)方法,

transformedBeanName(name)方法:解析name获取真正的beanName,因为传进来的name,有可能是真正的beanName,也有可能是FactoryBean创建的bean然后对应的name,也有可能是bean的alias(bean的别名),无论是这三则那个也好,对于spring来说,它需要的是beanName

2.2 getSingleton(beanName);

 

这里尝试从缓存中获取Bean

2.3 getObjectForBeanInstance方法

 2.3.1 getObjectForBeanInstance方法

在这个方法里面,大致也分为了两步,一步是对FactoryBean工厂生成的bean进行处理,一步则是对默认规则生成的bean进行处理,在这里spring不对按默认规则生成的bean进行任何处理,直接返回;如果用户想要获取的是FactoryBean创建的工厂bean,则直接在传入的name前加‘&’前缀

2.3.2  getObjectFromFactoryBean方法

 

2.3.3 doGetObjectFromFactoryBean

以上大致就是spring从缓存中加载bean,最后在调用postProcessObjectFromFactoryBean后处理器

3. 缓存中没有获取到bean

4. 获取单例bean:getSingleton的重载方法

进来之后,spring还是首先尝试从缓存中获取bean,如果确实没有,才来真正的创建bean(spring会把单例bean放入缓存中,提高效率),调用传进来的ObjectFactory的getObject方法,获取bean,ObjectFactory由createBean方法返回,创建bean的过程主要也在createBean方法中

beforeSingletonCreation()方法:记录当前bean为正在创建的bean

bean加载的大致过程就是这样的,接下来我们看一下正在创建bean的过程createBean方法

5. createBean方法:真正创建bean的方法

进入createBean方法

进入到createBean方法后,spring首先通过beanName或则设置的class属性来解析class,然后对bean的override方法进行处理,这里其实是对XML中replace-method和lookup-method进行处理,在spring中,spring就是把这两个属性放在了BeanDefinition中的OverrideMethod属性中,然后在实例化前调用实例化前的前置处理器

进入prepareMethodOverrides()方法

进入prepareMethodOverride方法

在这里我们看到spring获取对应方法名的对应个数,如果获取到对应方法名的个数为1,则说明改方法没有被重载,则直接标识,后续过程中则可以直接拿来用,节约解析开销

进入resolveBeforeInstantiation方法

进入这个方法后,里面主要的逻辑就是调用实例化前的后处理器,和调用实例化后的后处理器,为什么这里要调用实例化后的后处理器,因为在spring中,无论是怎么实例化的bean,spring都尽可能的会调用实例化的后处理器;因为如果返回的bean不为空spring便不会在调用普通bean的实例化过程

然后继续往下走,到doCreateBean方法,经过我们之前对spring源码的观看学习,发现spring大部分正在做实事的都是一do开头的方法,在这里bean的实例化也不例外

6. doCreateBean方法

进入doCreateBean方法后,spring先通过构造器/工厂配置创建BeanWrapper

BeanWrapper:可以看作是偏底层的 bean 包装器,提供了对标准 java bean 的分析和操作方法,包括获取和设置属性值、获取属性描述符,以及属性的读写特性等(可简单理解,这里为spring创建的空壳bean,还没有填充属性,初始化,AOP等后续功能的bean)

判断当前创建的bean是否运行循环依赖,是否是单例的,是否是正在创建的bean,如果都满足,则将当前bean对应的ObjectFactory放入到缓存中(也就是三级缓存),这一步也是为了解决循环依赖(这里放的ObjectFactory可以暂时理解成就是当前bean的空壳bean)

7.当前面的操作做完后,接下来就是spring的属性注入和初始化

8.经过属性注入和初始化后,spring还会对存在循环依赖的bean再次检查当前bean是否还存在循环依赖

如果从缓存中获取到了单例bean,则说明spring经过了循环依赖,如果获取到的单例bean不等于当前正在创建的bean,则说明当前bean还存在循环依赖,或则说当前bean在初始化的时候还做了其它操作(代理增强了当前bean);则spring会直接抛出异常,告诉用户当前Bean还存在循环依赖问题

9.最后在注册DisposableBeanIfNecessary

 ​​Spring 中不但提供了对于初始化方法的扩展入口,同样也提供了销毁方法的扩展入口,对 于销毁方法的扩展,除了我们熟知的配置属性 destroy-method方法外,用户还可以注册后处理 器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法
10.另外我们在看一下创建BeanWrapper的方法
createBeanInstance


进入到createBeanInstance方法后,首先先获取Class文件,然后在判断当前bean是否允许被创建,如果当前Bean不被允许创建,则直接报错抛出异常,然后在判断当前创建bean是否满足其对应的工厂规则,如果满足,则直接用其对应的工厂规则创建并返回对应的BeanWrapper对象

 如果工厂规则不存在,则利用构造函数创建对应的BeanWrapper,首先解析,确认具体的构造函数,因为一个bean可能存在多个构造函数,其次判断是否已经解析并确认了构造函数,如果已经解析了是有参构造函数,则直接调用对应的构造函数,创建并封装成对应的BeanWrapper对象,否则调用默认的构造函数创建并封装对应的BeanWrapper对象

 

11.进入默然构造方法创建Bean并封装成BeanWrapper对象
instantiateBean方法

进入到instantiateBean方法后,首先判断当前bean是否有需要覆盖或则替换的方法,如果有则需要通过cglb动态代理,因为可以在创建动态代理的过程中直接将动态方法植入类中,否则直接通过反射创建bean
12.initializeBean方法

 进入初始化方法,在执行初始化方法时,spring为用户提供了,多个接口用来让用户对生成的bean做扩展,入Aware回调接口和BeanPostPreccessors接口

总结

spring的bean的加载流程

1.spring 先对name进行解析,得到真正的beanName

2.尝试从缓存中获取bean,如果获取到了,则根据当前bean的规则进一步对当前bean做处理,然后直接返回当前bean

3.没有从缓存中获取到bean,则创建bean,首先检查当前bean是否不是单例的,并且存在循环依赖,如果满足则直接抛出异常,因为spring没有对多例bean存在循环依赖问题做处理

4.然后在通过从BeanDefinition中获取当前bean的所有信息,然后创建bean

5.创建单例bean,调用getSignleton的重载方法

5.1 首先记录当前bean的正在创建的状态,然后调用正在创建bean的方法createBean创建Bean

5.2 进入createBean,首先通过对应bean的创建规则(FactoryBean/构造器规则/默认规则)创建bean对应的BeanWapper对象

5.3 检查当前bean是否符合解决循环依赖的所有条件,如果都满足,则记录从BeanWrapper中获取到的bean对应的ObjectFactory对象放入到三级缓存中

5.4 然后在属性注入

5.5 然后在初始化,在初始化中,首先会经过Aware回调,其次在经过beanPostProcessors的前置处理方法,然后在真正的初始化,然后在经过beanPostProcessors的后置处理方法

5.6 最后在进行循环依赖检查,如果当前Bean还存在循环依赖,则直接报错

5.7 最后注册DisposableBeanIfNecessary

5.8 删除正在创建bean的状态

5.9 加入单例池中

最后笔者建议,真正想知道bean的加载流程的同学,还是去看笔者推荐的那篇文章,那篇文章才是真正对bean的加载流程的详细讲解;这里笔者相当于只是对笔者学习笔记的一个整理,还有很多没有记录,后续笔者在完善加强

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 是一个非常流行的开源框架,它提供了许多功能强大的模块和工具,使得 Java 应用程序的开发变得更加容易和高效。Spring底层原理和源码分析是理解 Spring 框架的关键。 Spring底层原理主要包括以下几个方面: 1. IoC(Inverse of Control,控制反转)容器:Spring 的 IoC 容器负责管理应用程序中的所有对象,包括创建、初始化、配置和销毁等操作。它通过依赖注入(Dependency Injection,DI)的方式将对象之间的依赖关系进行管理,实现了对象的松耦合和可重用性。 2. AOP(Aspect Oriented Programming,面向切面编程)框架:Spring 的 AOP 框架允许在应用程序中定义切面(Aspect),并将它们与其他对象进行织入(Weaving),从而实现横切关注点(Cross-Cutting Concerns)的统一处理,如事务管理、日志记录、安全控制等。 3. JDBC(Java Database Connectivity,Java 数据库连接)框架:Spring 的 JDBC 框架提供了一组简单、易用的 API,使得 Java 应用程序可以方便地访问和操作数据库,同时还支持事务管理、异常处理等功能。 4. MVC(Model-View-Controller,模型-视图-控制器)框架:Spring 的 MVC 框架提供了一种基于 MVC 设计模式的 Web 应用程序开发方式,它将请求和响应的处理分离,使得应用程序的逻辑层和视图层更加清晰和易于维护。 对于 Spring 框架的源码分析,可以从以下几个方面进行深入研究: 1. IoC 容器的实现原理:了解 Spring IoC 容器的实现原理,包括 Bean 的加载、实例化、属性注入、生命周期管理等方面,可以更好地掌握 Spring 的核心功能。 2. AOP 框架的实现原理:研究 Spring AOP 框架的实现原理,包括切面的定义、切点的匹配、通知的织入等方面,可以深入理解 AOP 技术的本质和应用。 3. JDBC 框架的实现原理:探究 Spring JDBC 框架的实现原理,包括数据源的配置、SQL 语句的生成、结果集的处理等方面,可以理解 JDBC 技术的底层实现和优化。 4. MVC 框架的实现原理:了解 Spring MVC 框架的实现原理,包括请求的处理流程、控制器的注册和映射、视图的解析和渲染等方面,可以深入了解 Web 应用程序的开发和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值