微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring IoC 容器加载流程简述

博文目录


IoC容器加载流程

IoC容器加载流程可以分成两个步骤

  • 将配置的各种 Bean 解析成为 BeanDeFinition
  • 遍历 BeanDeFinition,并缓存起来

注解形式的IoC容器加载流程

// 常见的写法,其实AnnotationConfigApplicationContext还有一个传入basePackages的构造函数
// 如果传入的是包路径,则通过BeanDeFinitionScanner扫描,找到候选组件将其封装成为BeanDeFinition,注册到容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Object bean = context.getBean("demo");
System.out.println(bean);

准备工作

初始化 AnnotationConfigApplicationContext 的时候,会预先注册几个底层基础架构工具类,他们以后置处理器的形式被注册,在容器初始化流程中发光发热. 然后再注册配置类,然后才是刷新容器

这些工具类中有两个非常重要

  • ConfigurationClasspostProcessor: 配置类解析器,负责解析配置类,主要是解析配置类上的 @PropertySource,@ComponentScan,@Import,@ImportSelector 注解以及配置类中由 @Bean 注解标注的方法. 解析 @ComponentScan 的时候会扫描其指定的 basePackages 路径,将标注有 @Component (@Repository,@Service,@Controller,@RestController 等含有 @Component 元注解,也会被扫描到),@ManagedBean,@Named 注解的类也解析到
  • AutowiredAnnotationBeanPostProcessor: 注解注入解析器,负责解析 @Autowired

将配置的各种 Bean 解析成为 BeanDeFinition

调用 refresh 的 invokebeanfactoryPostProcessors 方法,将自动或手动注册的各种 beanfactoryPostProcessors (包括 BeanDeFinitionRegistryPostProcessor) 按一定的顺序规则逐个调用其 postProcessBeanDeFinitionRegistry 和 postProcessbeanfactory 方法

这里其实主要就是工具类 ConfigurationClasspostProcessor 在发光发热,它解析到目前为止容器中所有 BeanDeFinition 中的配置类,将相关的组件候选全都注册成为 BeanDeFinition

遍历 BeanDeFinition,并缓存起来

调用 refresh 的 finishbeanfactoryInitialization 方法,遍历 beanNames,拿到对应 beanName 的 BeanDeFinition,符合生产条件(非抽象&是单例&非懒加载)的都调用 getBean(beanName) 来生产 Bean,并缓存到一级缓存(单例池)中

Bean 生产步骤

Bean 的创建可以分为三个步骤

  • 实例化: 就是通过工厂(@Bean)或反射(无参反射,有参构造函数反射)等完成 Bean 从无到有的第一步. ObjectBean 是不是在这里生效?
  • 填充属性: Bean 如果有 @Autowired / @Value 注解标注的属性,则需要做自动填充,主要由 AutowiredAnnotationBeanPostProcessor 来完成
  • 初始化: 调用各种 Aware 的相关属性注入方法,BeanPostProcessor 的 postProcessBeforeInitialization 方法 (包括 @postconstruct 指定的初始化方法),InitializingBean 的 afterPropertiesSet 方法,自定义的 init-method 方法,BeanPostProcessor 的 postProcessAfterInitialization 方法

生产完成之后,将该 Bean 缓存到一级缓存(单例池)中

Bean 的生命周期接口调用

beanfactory 的实现应该尽可能支持标准 Bean 生命周期接口. 全套初始化方法及其标准顺序如下

  • BeanNameAware 的 setBeanName
  • BeanClassLoaderAware 的 setBeanClassLoader
  • beanfactoryAware 的 setbeanfactory
  • EnvironmentAware 的 setEnvironment
  • EmbeddedValueResolverAware 的 setEmbeddedValueResolver
  • ResourceLoaderAware 的 setResourceLoader (仅在 Application Context 中适用)
  • ApplicationEventPublisherAware 的 setApplicationEventPublisher (仅在 Application Context 中适用)
  • MessageSourceAware 的 setMessageSource (仅在 Application Context 中适用)
  • ApplicationContextAware 的 setApplicationContext (仅在 Application Context 中适用)
  • ServletContextAware 的 setServletContext (仅在 Web Application Context 中适用) (ServletContext 可能是指在 Servlet 容器中运行的每一个应用)
  • BeanPostProcessors 的 postProcessBeforeInitialization,其中包括 @postconstruct 的处理与标注方法调用
  • InitializingBean 的 afterPropertiesSet
  • 自定义的 init-method 方法
  • BeanPostProcessors 的 postProcessAfterInitialization

BeanNameAware,BeanClassLoaderAware,beanfactoryAware 是在 Bean 初始化方法 initializeBean 里面调用

EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware 是在 ApplicationContextAwareProcessor 这个 BeanPostProcessor 里面的 postProcessBeforeInitiolization 方法调用

// 在 BeanPostProcessors 的 postProcessBeforeInitialization 中,InitDestroyAnnotationBeanPostProcessor会处理 @postconstruct 注解,会调用被该注解标注的方法,CommonAnnotationBeanPostProcessor 是 reader 注册的创世纪处理器之一
class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor

到这一步,bean已经生产好了,它们将一直驻留在 ApplicatonContext 中,直到该 ApplicatonContext 被销毁

关闭 beanfactory 时,以下生命周期方法适用

  • DestructionAwareBeanPostProcessors 的 postProcessBeforeDestruction,其中包括 @PreDestroy 的处理与标注方法调用
  • disposableBean 的 destroy
  • 自定义的 destroy-method 方法

Spring扩展接口和调用时机

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐