Spring之Bean生命周期源码分析(一)2

简介: Spring之Bean生命周期源码分析(一)

当前 BeanDefinition不存在 父BeanDefinition

在红框位置去判断 当前bean有没有父bean, 如果没有, 则判断当前 BeanDefinition有没有实例化 RootBeanDefinition, 然后去生成一个新的 RootBeanDefinition, 不管有没有实例化都生成

父子BeanDefinition具体可以看标题三, 如下图所示

网络异常,图片无法展示
|

最后会直接进入这个方法, 将当前 BeanDefinition放入 mergedBeanDefinitions 中

网络异常,图片无法展示
|

当前 BeanDefinition存在 父BeanDefinition

流程如下:

  • 获取当前 BeanDefinition 的 父BeanDefinition名字
  • 判断当前 beanName是否等于 parentBeanName
  • 不相等:
  • 递归 继续进行合并
  • 相等:
  • 获取 父BeanFactory
  • 如果 父Bean工厂 实现了 ConfigurableBeanFactory 接口则 递归合并
  • 若未实现则抛出异常

网络异常,图片无法展示
|

FactoryBean

这边会通过 beanName去判断当前 bean是不是一个 FactoryBean, 具体实现如下图所示

在 isFactoryBean(String name) 方法中, 第一行代码的降价在下面 FactoryBean标题下面

网络异常,图片无法展示
|

上图中, 我特意用红框圈出来一个方法, 这个方法的作用是: 通过 beanName去单例池中取数据, 但是这个时候是获取不到的, 因为我们还没有去生成 bean对象, 所以继续往下走

在下面代码中, 去做判断, 如果当前 beanName去取不到 BeanDefinition, 就去判断它的 父BeanDefinition有没有实现 FactoryBean

if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
   return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
复制代码

最后, 拿到合并之后的 BeanDefinition, 在往下走, 去判断 BeanDefinition的类型, 在判断是不是一个 FactoryBean, 在返回

网络异常,图片无法展示
|

获取FactoryBean对象

获取FactoryBean对象靠的是 getBean(String name)方法

网络异常,图片无法展示
|

我们可以看到, 这个方法的入参是在我们的 beanName前面增加了一个符号 &

我们进入这个方法内部去看一下

网络异常,图片无法展示
|

这里我们看到了熟悉的代码, 这行代码会根据你传入的 name不同而有所变化

String beanName = transformedBeanName(name);
复制代码

网络异常,图片无法展示
|

如上图所示, 可以看到, 我们在 实例化非懒加载单例Bean的时候, 有三个地方调用到了 getBean(String name)方法, 且第一次调用在 beanName前加了符号 &

在 getBean(String name)中, 会通过 transformedBeanName 方法去获取 beanName

然后根据获取到的 beanName去单例池中查找 获取单例对象, 如果获取到了单例对象, 那么会根据 bean的单例对象, beanName和传进来的 name去获取 bean实例

如果没有获取到了单例对象, 则会继续进行 bean的生命周期, 最后生成 bean的单例对象, 具体可以看我的下一篇Spring文章

创建 Bean对象

创建Bean对象就要用到 getBean(String beanName)方法了, 对于 getBean(String beanName) 方法的源码解析, 将作为下篇Spring系列文章发布在我的: Spring专栏

getBean 方法就是去创建一个Bean对象, 之前我还简单的手写模拟过整个过程, 感兴趣的可以去看一下Spring之手写模拟Spring Bean的创建

实现SmartInitializingSingleton接口

我们来实现这个接口, 会自动生成一个方法

网络异常,图片无法展示
|

通过上面的分析, 可以知道, 这个方法的执行时间是: 所有单例Bean都实例化之后

因为是在所有Bean实例化之后才去判断当前的Bean有没有实现这个接口

网络异常,图片无法展示
|

三、合成BeanDefinition-父子BeanDefinition

生成父子 BeanDefinition代码如下

<bean id="juejin1" class="com.ningxuan.service.Juejin" scope="prototype"/>
<bean id="juejin2" class="com.ningxuan.service.Juejin" parent="juejin1"/>
复制代码

网络异常,图片无法展示
|

因为child的父BeanDefinition是parent,所以会继承parent上所定义的scope属性。

而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整的child的BeanDefinition。


目录
相关文章
|
1天前
|
Java 应用服务中间件 Spring
Spring系列文章:Bean的作⽤域
Spring系列文章:Bean的作⽤域
|
1天前
|
XML 前端开发 Java
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
4 0
|
1天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
2 0
|
1天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
5 0
|
1天前
|
存储 Java 对象存储
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
9 0
|
1天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
1天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
21 1
|
1天前
|
XML Java 数据格式
Spring Bean
【4月更文挑战第30天】Spring Bean
17 0
|
1天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
32 2
|
1天前
|
XML Java 数据格式
谈谈 Spring 中 Bean 的生命周期?
谈谈 Spring 中 Bean 的生命周期?
20 1