Spring - 浅谈Spring容器装配Bean的过程

前言

Spring中核心之一就是Spring容器(或者IoC容器),一切Spring bean都存储在Spring容器内

需要搞清楚:

  1. Bean容器
  2. Bean加载过程

Spring容器

IoC,控制反转使得我们不需要自己创建对象,而是由容器接管,让容器注入到我们需要的地方

这里就涉及到了Spring容器,Spring容器有两种:

  • BeanFactory:较低级的容器,负责配置、创建、管理Bean
  • ApplicationContext:较为高级的容器(应用上下文),是BeanFactory的子接口,在其基础上还管理着Bean和Bean之间的依赖关系、上下文信息

正如同它们的名字,BeanFactory,Bean的工厂,用于创建管理Bean , ApplicationContext,应用上下文,不在局限与Bean,而是拥有整个应用的信息


继承体系

在这里插入图片描述

  • BeanFactory:bean容器的顶级接口,提供了getBean、getType、getAliases等方法
  • HierarchicalBeanFactory:提供父容器的访问功能getParentBeanFactory
    ListableBeanFactory:提供了批量获取Bean、BeanName的方法Map<String, T> getBeansOfType(@Nullable Class<T> type)
    AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理
    这三个是BeanFactory的子接口

在这里插入图片描述

  • 低级容器相关类:DefaultListableBeanFactory等,
    DefaultListableBeanFactory是最主要的BeanFactory,实现了父BeanFactory所有功能,以Map的形式存储Bean,可以注册BeanDefinition(配置文件bean抽象为类)

在这里插入图片描述

  • 高级容器:ApplicationContext,其主要的实现类:
    ClassPathXmlApplicationContext:默认从类路径加载配置文件
    FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
    AnnotationConfigApplicationContext:解析依赖注入的JavaConfig

在这里插入图片描述
ApplicationContext本质上也是BeanFactory,但不仅仅是Bean容器


BeanFactory与ApplicationContext区别

两种虽然都是Spring容器,但有很大的区别:

  • BeanFactory只是Bean容器,支持Bean的配置、创建、管理,是Spring的基础,但BeanFactory是Spring中比较原始的Factory,它不支持AOP、Web等Spring插件
  • ApplicationContext不仅仅是Bean容器
    ApplicationContext继承了BeanFactory,但ApplicationContext不仅包含了BeanFactory的所有功能,还支持Spring的各种插件,
    如国际化MessageResource接口,事件机制Event与Listener、底层资源访问ResourceLoader
    还以一种面向框架的方式工作以及对上下文进行分层和实现继承。
  • BeanFactory是Spring框架的基础设施,面向Spring本身;而ApplicationContext面向使用Spring的开发者,相比BeanFactory提供了更多面向实际应用的功能,几乎所有场合都可以直接使用ApplicationContext而不是底层的BeanFactory

BeanDefinition

A BeanDefinition describes a bean instance, which has property values,constructor argument values, and further information supplied by concrete implementations.

这是BeanDefinition的注释:一个BeanDefinition用于描述一个Bean实例,具体该实例的各种信息

BeanDefinition接口的子抽象类:

在这里插入图片描述

拥有许多字段用于描述一个Bean实例,这对应着一个Bean标签或者注解的各种子标签、属性

具体的由XML的bean标签到BeanDefinition是一个很复杂的过程:
Spring-BeanFactory基本工作流程

大致:

  1. BeanFactory在初始化时调用loadBeanDefinitions方法
  2. 我们使用的ApplicationContext获得url或者class,一步步调用找到bean对应的配置文件、类
  3. XmlBeanDefinitionReader调用doLoadDocument方法,读取xml文件的信息读取文件解析生成Document对象(Resource解析)
  4. 加载生成BeanDefinition
  5. beanDefinitionMap是IOC容器中实际存储Bean(BeanDefinition)的地方

在这里插入图片描述
内部有很多细节,详情看上面大佬的文章
总之,我们把bean标签的各种属性封装成了一个BeanDefinition,注册到了容器


PostProcessor

  • BeanFactoryPostProcessor
    bean工厂的bean属性处理容器,可以管理我们的bean工厂内所有的beandefinition数据,可以随心所欲的修改属性

  • BeanPostProcessor
    bean的属性处理器,即可以修改Bean的属性,操作Bean的实例化

在这里插入图片描述

这种处理Bean、BeanFactory的操作最典型的就是AOP


一个很复杂的面试题

Spring中Bean的生命周期:

  • 开始初始化容器
  • 加载BeanFactoryPostProcessor实现类
  • 执行BeanFactoryPostProcessor的postProcessBeanFactory方法
  • 加载BeanPostProcessor实现类
  • 实例化业务bean
  • Aware接口族调用
  • 执行BeanPostProcessor实现类的postProcessBeforeInitialization方法
  • 执行InitializingBean实现类的afterPropertiesSet方法
  • 执行bean的init-method属性指定的初始化方法
  • 执行BeanPostProcessor实现类的postProcessAfterInitialization方法
  • 初始化完成
  • 关闭容器,执行DiposibleBean实现类的destory执行bean的destroy-method属性指定的初始化方法

总结

大致看下来,Spring容器装配bean的过程:

  • 初始化容器,加载后置处理器
  • 通过设置的BeanFactory或ApplicationContext获得配置、类的路径
  • 解析XML、注解配置, 获得对应的BeanDefinition,注册到beanDefinitionMap(容器)中

Spring源码太复杂了,暂时不是我能够看懂的
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值