Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

本文深入探讨了Spring框架中Bean实例化的原理,包括BeanFactory的getBean方法思路、Spring如何解决循环依赖问题,特别是单例模式下的属性依赖。此外,文章还详细介绍了Spring Bean的生命周期流程及其案例。通过对Spring框架的深入剖析,读者将更好地理解Spring如何管理Bean的创建、初始化和销毁过程。
摘要由CSDN通过智能技术生成

🚀 优质资源分享 🚀

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统
作者:@pdai本文为作者原创,转载请注明出处:https://blog.csdn.net/pengdai/p/16421879.html

内容目录


上文,我们看了IOC设计要点和设计结构;以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的;容器中存放的是Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等。那么如何从BeanDefinition中实例化Bean对象呢,这是本文主要研究的内容?@pdai

引入

上文,我们看了IOC设计要点和设计结构;以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的;容器中存放的是Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等。那么如何从BeanDefinition中实例化Bean对象呢?

本文主要研究如何从IOC容器已有的BeanDefinition信息,实例化出Bean对象;这里还会包括三块重点内容:

  • BeanFactory中getBean的主体思路
  • Spring如何解决循环依赖问题
  • Spring中Bean的生命周期

BeanFactory中getBean的主体思路

上文中我们知道BeanFactory定义了Bean容器的规范,其中包含根据bean的名字, Class类型和参数等来得到bean实例。

// 根据bean的名字和Class类型等来得到bean实例 
Object getBean(String name) throws BeansException;    
Object getBean(String name, Class requiredType) throws BeansException;    
Object getBean(String name, Object... args) throws BeansException;
 T getBean(Class requiredType) throws BeansException;
 T getBean(Class requiredType, Object... args) throws BeansException;

初步的思考

上文我们已经分析了IoC初始化的流程,最终的将Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等;

这样我们初步有了实现Object getBean(String name)这个方法的思路:

  • 从beanDefinitionMap通过beanName获得BeanDefinition
  • 从BeanDefinition中获得beanClassName
  • 通过反射初始化beanClassName的实例instance
    • 构造函数从BeanDefinition的getConstructorArgumentValues()方法获取
    • 属性值从BeanDefinition的getPropertyValues()方法获取
  • 返回beanName的实例instance

由于BeanDefinition还有单例的信息,如果是无参构造函数的实例还可以放在一个缓存中,这样下次获取这个单例的实例时只需要从缓存中获取,如果获取不到再通过上述步骤获取。

(PS:如上只是我们初步的思路,而Spring还需要考虑各种设计上的问题,比如beanDefinition中其它定义,循环依赖等;所以我们来看下Spring是如何是如何实现的)

Spring中getBean的主体思路

BeanFactory实现getBean方法在AbstractBeanFactory中,这个方法重载都是调用doGetBean方法进行实现的:

public Object getBean(String name) throws BeansException {
  return doGetBean(name, null, null, false);
}
public  T getBean(String name, Class requiredType) throws BeansException {
 return doGetBean(name, requiredType, null, false);
}
public Object getBean(String name, Object... args) throws BeansException {
 return doGetBean(name, null, args, false);
}
public  T getBean(String name, @Nullable Class requiredType, @Nullable Object... args)
 throws BeansException {
 return doGetBean(name, requiredType, args, false);
}

我们来看下doGetBean方法(这个方法很长,我们主要看它的整体思路和设计要点):

// 参数typeCheckOnly:bean实例是否包含一个类型检查
protected  T doGetBean(
 String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
 throws BeansException {

 // 解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
 String beanName = transformedBeanName(name);
 Object beanInstance;

 // Eagerly check singleton cache for manually registered singletons.
 Object sharedInstance = getSingleton(beanName);
 if (sharedInstance != null && args == null) {
 // 无参单例从缓存中获取
 beanInstance = getObjectForBeanInstance(sharedInstance
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值