• 注解版本-分析Spring容器创建流程


    目录

    一、AnnotationConfigApplicationContext

    二、refresh()

    2.1 prepareRefresh

    2.3 obtainFreshBeanFactory

    2.4 prepareBeanFactory

    2.5 postProcessBeanFactory

    2.6 invokeBeanFactoryPostProcessors

    2.7 registerBeanPostProcessors

    2.8 initMessageSource

    2.9 initApplicationEventMulticaster

    2.10 onRefresh

    2.11 registerListeners

    2.12 finishBeanFactoryInitialization

    2.13 finishRefresh


    以注解版本分析Spring容器创建流程

    一、AnnotationConfigApplicationContext

    利用AnnotationConfigApplicationContext创建ioc容器,可将自定义配置类(例如标识@Configuration注解)来导入组件。

    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestLifeCycleConfig.class);
    

    因为AnnotationConfigApplicationContext继承GenericApplicationContext若是没指定beanFactory容器对象,则在GenericApplicationContext的构造函数中会默认创建一个类型为DefaultListableBeanFactory的容器对象通过register方法将自定义的配置类注册到容器中,接着通过refresh方法刷新容器。

    二、refresh()

    ioc容器创建环境对象、加载配置文件、注册beanFactory、bean后置处理器、监听器、创建单实例非延迟加载组件等功能是通过AbstractApplicationContextrefresh方法完成。

    refresh方法中,先将该方法进行同步处理,目的是防止多线程同时刷新容器。 

    1. public void refresh() throws BeansException, IllegalStateException {
    2. synchronized (this.startupShutdownMonitor) {
    3. // Prepare this context for refreshing.
    4. //为刷新容器做准备,例如设置closed、active属性、加载配置文件、创建环境对象等
    5. prepareRefresh();
    6. // Tell the subclass to refresh the internal bean factory.
    7. //获取beanFactory容器对象
    8. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    9. // Prepare the bean factory for use in this context.
    10. //设置容器的类加载器、添加一些bean后置处理器等
    11. prepareBeanFactory(beanFactory);
    12. try {
    13. // Allows post-processing of the bean factory in context subclasses.
    14. postProcessBeanFactory(beanFactory);
    15. // Invoke factory processors registered as beans in the context.
    16. //创建实现BeanFactoryPostProcessor接口的实现类并运行对应实现接口方法
    17. invokeBeanFactoryPostProcessors(beanFactory);
    18. // Register bean processors that intercept bean creation.
    19. //创建实现BeanPostProcessor接口的实现类并将对象加到容器的BeanPostProcessor集合中,在后续容器创建初始化组件对象时,调用对应方法
    20. registerBeanPostProcessors(beanFactory);
    21. // Initialize message source for this context.
    22. //初始化国际化配置
    23. initMessageSource();
    24. // Initialize event multicaster for this context.
    25. //初始化事件监听多发器
    26. initApplicationEventMulticaster();
    27. // Initialize other special beans in specific context subclasses.
    28. //子类可重写该方法初始化一些特殊的组件对象
    29. onRefresh();
    30. // Check for listener beans and register them.
    31. //注册容器中的事件监听器
    32. registerListeners();
    33. // Instantiate all remaining (non-lazy-init) singletons.
    34. //实例化容器中剩余的非延迟加载的单实例组件
    35. finishBeanFactoryInitialization(beanFactory);
    36. // Last step: publish corresponding event.
    37. //完成容器刷新,清除缓存和发布容器刷新完成事件等
    38. finishRefresh();
    39. }
    40. catch (BeansException ex) {
    41. ...
    42. }
    43. finally {
    44. // Reset common introspection caches in Spring's core, since we
    45. // might not ever need metadata for singleton beans anymore...
    46. resetCommonCaches();
    47. }
    48. }
    49. }

    2.1 prepareRefresh

    prepareRefresh方法主要是在容器刷新前准备一些环境,例如设置closed、active属性,加载配置文件、创建环境对象等。

    1. protected void prepareRefresh() {
    2. // Switch to active.
    3. this.startupDate = System.currentTimeMillis();
    4. this.closed.set(false);
    5. this.active.set(true);
    6. if (logger.isDebugEnabled()) {
    7. if (logger.isTraceEnabled()) {
    8. logger.trace("Refreshing " + this);
    9. }
    10. else {
    11. logger.debug("Refreshing " + getDisplayName());
    12. }
    13. }
    14. // Initialize any placeholder property sources in the context environment.
    15. //加载配置文件,例如web环境下的容器对象通过该方法事先加载配置文件
    16. initPropertySources();
    17. // Validate that all properties marked as required are resolvable:
    18. // see ConfigurablePropertyResolver#setRequiredProperties
    19. //校验配置文件
    20. getEnvironment().validateRequiredProperties();
    21. // Store pre-refresh ApplicationListeners...
    22. //为事件监听器做一些准备
    23. if (this.earlyApplicationListeners == null) {
    24. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    25. }
    26. else {
    27. // Reset local application listeners to pre-refresh state.
    28. this.applicationListeners.clear();
    29. this.applicationListeners.addAll(this.earlyApplicationListeners);
    30. }
    31. // Allow for the collection of early ApplicationEvents,
    32. // to be published once the multicaster is available...
    33. this.earlyApplicationEvents = new LinkedHashSet<>();
    34. }

    2.3 obtainFreshBeanFactory

    obtainFreshBeanFactory方法告诉父类刷新容器例如设置序列号id等并返回容器对象

    2.4 prepareBeanFactory

    prepareBeanFactory方法是为在上下文中使用beanFactory容器对象做一些提前准备,例如设置类加载器、设置忽略依赖注入接口、设置可依赖注入的组件、添加部分Bean后置处理器等。

    1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    2. // Tell the internal bean factory to use the context's class loader etc.
    3. //设置类加载器、组件表达式解析器
    4. beanFactory.setBeanClassLoader(getClassLoader());
    5. beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    6. beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    7. // Configure the bean factory with context callbacks.
    8. //添加bean后置处理器,ApplicationContextAwareProcessor后置处理器可处理实现EnvironmentAware等xxAware接口的实现类,调用setXX方法将对应组件对象传给实现类
    9. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    10. //设置不可直接依赖注入的接口类
    11. beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    12. beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    13. beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    14. beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    15. beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    16. beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    17. // BeanFactory interface not registered as resolvable type in a plain factory.
    18. // MessageSource registered (and found for autowiring) as a bean.
    19. //设置可直接通过@Autowired等依赖注入的组件
    20. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    21. beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    22. beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    23. beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    24. // Register early post-processor for detecting inner beans as ApplicationListeners.
    25. //添加解析事件监听器的bean后置处理器
    26. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    27. // Detect a LoadTimeWeaver and prepare for weaving, if found.
    28. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    29. beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    30. // Set a temporary ClassLoader for type matching.
    31. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    32. }
    33. // Register default environment beans.
    34. //注册环境对象
    35. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    36. beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    37. }
    38. if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    39. beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    40. }
    41. if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    42. beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    43. }
    44. }

    2.5 postProcessBeanFactory

    postProcessBeanFactory方法允许AbstractApplicationContext的子类重写该方法为容器做一些后置处理,例如GenericWebApplicationContext,而DefaultListableBeanFactory没重写该方法,还是跟父类一样为空方法

    2.6 invokeBeanFactoryPostProcessors

    invokeBeanFactoryPostProcessors方法是用来创建实现BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor接口的实现类对象并运行对应的方法。

    1)先创建BeanDefinitionRegistryPostProcessor接口的实现类

    按照优先级顺序,

    1、创建实现PriorityOrdered接口的实现类对象并调用postProcessBeanDefinition方法

    2、创建实现Ordered接口的实现类对象并调用postProcessBeanDefinition方法

    3、创建没实现PriorityOrdered、Ordered接口的实现类对象并调用postProcessBeanDefinition方法

    2)先创建BeanFactoryPostProcessor接口的实现类

    按照优先级顺序,

    1、创建实现PriorityOrdered接口的实现类对象并调用postProcessBeanFactory方法

    2、创建实现Ordered接口的实现类对象并调用postProcessBeanFactory方法

    3、创建没实现PriorityOrdered、Ordered接口的实现类对象并调用postProcessBeanFactory方法

    BeanDefinitionRegistryPostProcessor(继承BeanFactoryPostProcessor):可自定义向容器添加beanDefinition。

    BeanFactoryPostProcessor:可获取容器的beanDefinition集合进行操作。

    例如容器内置的ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,该类通过postProcessBeanDefinitionRegistry方法扫描容器的配置类,解析配置类得到beanDefinition组件并注册到容器中。

    参考Spring-分析BeanFactoryPostProcessor后置处理器_Just-Today的博客-CSDN博客

    2.7 registerBeanPostProcessors

    registerBeanPostProcessors方法主要是创建实现了BeanPostProcessor接口的实现类对象并加到容器的BeanPostProcessor集合中,在后续容器创建初始化组件时遍历BeanPostProcessor集合调用对应后置处理方法。

    按照优先级顺序

    1、创建实现PriorityOrdered接口的实现类对象

    2、创建实现Ordered接口的实现类对象

    3、创建没实现PriorityOrdered、Ordered接口的实现类对象

    不同的BeanPostProcessor接口,执行顺序不同

    1、InstantiationAwareBeanPostProcessor:在创建组件对象之前,给bean后置处理器一个机会,返回该组件的代理对象

    2、MergedBeanDefinitionPostProcessor:在组件创建之后,可对RootBeanDefinition进行操作

    参考什么是MergedBeanDefinition?_jiangjun316的博客-CSDN博客

    3、BeanPostProcessor:在组件初始化前后

    4、DestructionAwareBeanPostProcessor:在组件销毁之前

    参考

    分析-BeanPostProceesor后置处理器_Just-Today的博客-CSDN博客

    2.8 initMessageSource

    初始化国际化配置

    2.9 initApplicationEventMulticaster

    初始化事件监听多发器

    2.10 onRefresh

    子类可重写该方法初始化一些特殊的组件对象

    2.11 registerListeners

    注册容器中的事件监听器

    2.12 finishBeanFactoryInitialization

    实例化容器中剩余的非延迟加载的单实例组件

    可参考spring-bean生命周期_Just-Today的博客-CSDN博客的4、创建组件对象(单例)章节

    2.13 finishRefresh

    完成容器刷新,清除缓存和发布容器刷新完成事件等
     

  • 相关阅读:
    基于springboot+vue开发的教师工作量管理系
    web分享会
    Fastjson_1.2.24_unserialize_rce漏洞复现
    SpringBoot通过@Cacheable注解实现缓存功能
    RMI反序列化学习
    100天掌握网络安全知识点!
    Java学习笔记(十三)
    vue 之 Quill编辑器封装
    TypeScript(基础篇)day01
    工商银行新一代银行移动开发平台建设研究
  • 原文地址:https://blog.csdn.net/weixin_37607613/article/details/126217559