Spring源码学习笔记(3)——容器的功能扩展 一. 引入ApplicationContext接口 前面的介绍都是基于BeanFactory接口和它的默认实现XmlBeanFactory的,但是Spring体系中还有一个重要的接口:ApplicationContext。ApplicationContext在BeanFactory上进行了一些扩展,功能更为强大。可以理解为:BeanFactory是Spring容器内部使用的,而ApplicationContext是暴露给应用使用的。除非在一些特殊情况下,否则
一 refresh源码分析 @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. //准备刷新上下文环境 prepareRefresh(); // Tell th
我们知道,spring 的启动其实就是容器的启动,而一般情况下,容器指的其实就是上下文 ApplicationContext。
之前通过debug的方式详细了解了SpringBoot启动的配置文件加载和容器初始化的相关的工作。但是对于核心的refresh()没有进行解析。而spring对于SpringApplication的准备工作的最终处理都是在refresh中执行的。所以深入理解refresh是理解spring的基础。而我们之前的学习为我们理解refresh打下了坚实的基础。甚至我们也猜测了后置处理器的工作方式,所以个人感觉理解refresh不会遇到特别难的地方。这里写一点个人学习的小经验。
今天带大家解读refresh()方法的第三个方法prepareBeanFactory(),通过对refresh()的一步步解读,想必有一天小伙伴们能揭开Spring的神秘面纱。
它的内部主要会调用 12 个方法,我们把它们称为 refresh 的 12 个步骤:
前面我们了解了bean的实例化过程,依赖注入,大体上对一个bean的创建有了认知,那么现在从spring启动来看它的一个架构,本来是想把配置类扫描的也加载本章,但两个主题并不相同,就拆开了。
这次我们从源码角度来聊聊BeanFactory和ApplicationContext的关系,讲一些网上文章不曾提到的点。
接上回 Spring5源码学习(2) ,分析完register(annotatedClasses);后,现在来看一下refresh();方法。
随着SpringBoot的普及,Spring的使用也越来越广,在某些场景下,我们无法通过注解或配置的形式直接获取到某个Bean。比如,在某一些工具类、设计模式实现中需要使用到Spring容器管理的Bean,此时就需要直接获取到对应的Bean。
根据 refresh 流程,当 obtainFreshBeanFactory 执行结束后,下一步会执行 prepareBeanFactory ,顾名思义,这个方法主要是准备 BeanFactory,下面一起看一看这部分逻辑。
BeanFactoryPostProcessor支持对IoC容器内部的所有BeanDefinition进行定制化修改, 并且可以根据IoC容器内部的BeanFactory进行Bean属性值的适配。
IoC容器的启动和刷新方法在AbstractApplicationContext中定义,即refresh()方法:
在obtainFreshBeanFactory方法会完成BeanFactory对象的创建。
1、找准入口 ,使用ClassPathXmlApplicationContext加载配置文件,用于加载classPath下的配置文件
在 Spring 框架中,每个应用程序上下文(ApplicationContext)管理着一个 BeanFactory,BeanFactory 主要负责 Bean 定义的保存、Bean 的创建、Bean 之间依赖的自动注入等。应用程序上下文则是对 BeanFactory 和 Bean 的生命周期中的各个环节进行管理,并且提供扩展接口允许用户对 BeanFactory 和 Bean 的各个阶段进行定制,本文从以下三个点进行切入讲解。
容器底层用DefaultListableBeanFactory,即实现了BeanDe finitionRegistry,又实现了BeanFactory java配置 :
invokeBeanFactoryPostProcessors 会执行 BeanFactory 的后置处理器。看到这里会有疑问:
本章是《spring4.1.8初始化源码学习三部曲》系列的终篇,重点是学习AbstractApplicationContext类的refresh()方法;
【3】prepareBeanFactory 对刚创建的bean工厂进行设置,源码分析:
接上文 Spring5源码分析(三)refresh方法 中已经讲到了refresh()中的postProcessBeanFactory(beanFactory);方法。
还记得我在这篇博文:【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析) 里留了几个非常重要,但是没有解释的方法。其中有一个非常重要的方法ApplicationContext#refresh()方法就是提到两次但都暂时忽略了(因为有父子容器,所以会刷新两次容器~)
因为是基于 java-config 技术分析源码,所以这里的入口是 AnnotationConfigApplicationContext ,如果是使用 xml 分析,那么入口即为 ClassPathXmlApplicationContext ,它们俩的共同特征便是都继承了 AbstractApplicationContext 类,而大名鼎鼎的 refresh()便是在这个类中定义的。我们接着分析 AnnotationConfigApplicationContext 类,源码如下:
BeanFactoryPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下
ApplicationContext是对BeanFactory的扩展,实现BeanFactory的所有功能,并添加了事件传播,国际化,资源文件处理等。
Spring 容器最基本最基本的接口就是BeanFactory。BeanFactory负责配置,创建、配置Bean,其中有一个子接口ApplicationContext,也被称为Spring上下文。容器同时还管理这Bean和Bean之间的依赖关系
前面两篇文章分析了super(parent)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码,
在之前的学习中,我们大概的学习了springBoot的初始化。大概得流程是springApplication读取通过读取spring.factories文件中SpringBootAppliationinitlizer和springApplicationRunabaleListenner相关的接口。其中listenner伴随着SpringBoot应用启动的全过程,在每个阶段运行结束的时候都会将IOC容器传入并通知所有的listenner对象,其中ConfigFileApplicationListener在SpringApplication类中就开始对配置进行解析。而在IOC初始化结束,praperContent阶段,调用this.applyInitializers(context)的时候就将解析注解的和配置的后置处理器(实现了BeanDefinitionRegistryPostProcessor得类)全部已经注册到beanFactory中的后置处理器map中,之后通过load方法将启动类加载到beanFactory中。这一切都准备好之后,进入SpringBoot的核心启动类中。在核心类中,首先做一些准备工作包括一些容器属性通过配置文件的新值覆盖等。之后获取实现了BeanDefinitionRegistryPostProcessor接口的类进行后置处理。先进行排序,找到优先级比较高的配置解析类等。然后使用先前parperContent中applyInitializers注册的ConfigurationClassPostProcessor进行注解的解析,通过这个后置处理器的处理所有的类都注册到beanDefinitionMap中。之后通过实现了BeanDefinitionRegistryPostProcessor和Order具有排序的接口,逐个调用
Spring 容器首先会执行 org.springframework.context.annotation.AnnotationConfigApplicationContext 的一个方法:
概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解。俗话说知己知彼,百战不殆。当你对Spring 掌握熟透之后,也就没什么能过阻拦你在开发路上前进了。 IOC 总体来说有两处地方最重要,一个是创建Bean容器,一个是初始化。在本文中,主要为大家讲解了 IOC Bean 容器创建过程。后续将会补上初始化部分的知识。 为了保持文章的严谨性,如果读者发现我哪里说错了请一定不吝指出,非常希望可以听到读者的声
上篇文章对spring核心启动方法refresh做了整体的解读,但是只是泛泛而谈,接下来会出一系统文章对每个方法的源码进行深刻解读。
BeanPostProcessor接口是Spring中一个非常重要的接口,它的接口定义如下
接口org.springframework.context.ApplicationContext表示spring上下文,下面2个实现类
对于AbstractApplicationContex#refresh()方法逻辑,可所谓是贯通spring框架核心逻辑,溪源在debug过程中,理解起来也是懵懵懂懂,自己也买了《Spring源码深度解析》书籍学习其思想和实现逻辑,经过不断的整理学习总结,最终诞生这篇文章,方便后面自己忘记了查看和理解。 下面开始正式踏入refresh方法的整体概览浅析。
Spring通过一个配置文件描述Bean和Bean之间的依赖关系,利用Java反射功能实例化Bean,并建立Bean之间的依赖关系。
Spring 作为优秀的开源框架,它为我们提供了丰富的可扩展点,除了前面提到的 Aware 接口,还包括其他部分,其中一个很重要的就是 BeanPostProcessor。这篇文章主要介绍 BeanPostProcessor 的使用以及其实现原理。我们先看 BeanPostProcessor 的定位:
通过 Debug 可以看出 refreshBeanFactory() 这一步调用的是 org.springframework.context.support.GenericApplicationContext#refreshBeanFactory 中实现的方法。
在Java的应用开发中,Spring框架是广泛使用的一个工具,它提供了依赖注入(DI)和面向切面编程(AOP)等功能。在Spring中,BeanFactory和FactoryBean是两个关键的概念,它们在管理和创建Bean实例时发挥着重要作用。本文将深入探讨BeanFactory和FactoryBean的区别,并提供相应的代码示例。
理解spring中的BeanFactory和FactoryBean的区别与联系指出两点:
Bean组件是 Spring核心中的重点,Spring 就是面向Bean编程的(Bean Oriented Programming:BOP)就像Object 对OOP的意义一样,没有对象的概念就像没有面向对象的编程,在Spring中没有Bean也就没有Spring存在的意义。我们使用 Spring的主要一个原因就是 Spring会把对象之间的依赖关系转而用配置文件来管理。也就是依赖注入机制。而这个注入关系在一个叫 IOC的容器中管理,而IOC容器就是被Bean包裹的对象。Spring正是通过把对象包装在Bean中从而达到管理这些对象及做一系列额外操作的目的。
AbstractApplicationContext的refresh()方法是spring的核心,在其中完成了容器的初始化。我们先简单看下业务Bean的声明流程:
最近抽空总结一下之前通用的Spring框架所出现的问题和异常情况,当创建属于自己的ApplicationContext对象的时候,经常会遇到这么几条异常消息:
这个接口是beanFactory的扩展接口,调用时机在spring在读取beanDefinition信息之后,实例化bean之前。
BeanFactory顾名思义:生产和管理bean的工厂。它是IOC容器的规范接口,Spring中有很多个BeanFactory的实现,如DefaultListableBeanFactory,XmlBeanFactory,ClassPathXmlApplicationContext,ApplicationContext等等。
现在一般使用 ApplicationContext,不建议使用 BeanFactory。
在Spring IoC容器的设计中,两个主要容器系列 实现BeanFactory接口的简单容器系列 这系列容器只实现了容器的最基本功能 ApplicationContext应用上下文 作为容器的高级形态而存在。在简单容器的基础上,增加了许多面向框架的特性,同时对应用环境作了许多适配。 1 Spring的IoC容器系列 对IoC容器的使用者来说,我们经常接触到的BeanFactory和ApplicationContext都可以看成是容器的具体表现形式。 如果深入到Spring的实现中去看,所说的IoC容
Spring是一个非常活跃的开源框架;它是一个基于Core来架构多层JavaEE系统的框架,它的主要目的是简化企业开发。Spring以一种非侵入式的方式来管理你的代码,Spring提倡“最少侵入,这也意味着你可以适当的时候安装或卸载Spring。
欢迎来到本篇技术博客,今天我们将探讨Spring框架中两个重要的容器:BeanFactory 和 ApplicationContext。这两者在Spring应用程序中扮演着关键的角色,但它们之间存在一些重要的区别。在本文中,我们将详细讨论这些区别,并通过代码示例演示它们的用法。
领取专属 10元无门槛券
手把手带您无忧上云