欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring框架核心讲解

程序员文章站 2022-07-10 18:57:20
文章目录BeanFactoryApplicationContextBeanFactory  在Spring中,有许许多多的核心功能ApplicationContext...



概述

容器功能是Spring最基本最核心的功能,很多其他功能都是建立在容器功能之上(容器的核心功能由BeanFactory定义)。
容器功能实现了对象创建和对象使用的解耦,对象的使用者只需要从容器获取对象,而无需关注创建对象的细节,容器会根据相应的配置来创建对象,所以还需要向容器提供创建相应对象的配置信息(用BeanDefinition对象来保存)。对象使用者只需要从容器获取对象,而将对象创建的工作交由容器完成,这就是控制反转IOC,而容器进行对象创建使用了依赖注入DI的方式。
Spring提供了多种方式来创建BeanDefinition对象,可以直接创建BeanDefinition对象,也可以通过解析xml或者properties文件来获取BeanDefinition对象,还可以通过解析注解获取BeanDefinition对象。xml曾是最流行的方式,现如今注解成为了首选
上下文ApplicationContext以BeanFactory为基础,实现了更多的功能,如广播、资源加载等功能,且在初始化过程中提供了许多默认设置并预留了许多扩展功能
SpringMVC使用ApplicationContext来管理Bean,并通过DispatherServlet(Servlet的实现类)来做统一的请求入口,完成请求的分发
SpringBoot可以将项目打包成一个可运行的jar包(有启动类,启动类拥有main方法),启动过程中会创建ApplicationContext来管理Bean。对于Web项目,还可以启动一个Servlet容器。SpringBoot通过自动配置来简化开发过程,提高开发效率

继承关系

BeanFactory

Spring框架核心讲解

  • BeanFactory:作为最顶层的BeanFactory,它定义了最基本的容器功能,即通过容器获取Bean。
  • HierarchicalBeanFactory:作为BeanFactory的直接子接口,它定义了父子容器的功能,此时,通过某容器去获取Bean时,如果无法获取到,会到其父容器去获取。
  • ListableBeanFactory:作为BeanFactory的直接子接口,它定义了根据注解或类型等过滤,获取多个Bean的方法。
  • AutowireCapableBeanFactory:作为BeanFactory的直接子接口,它定义了创建对象以及依赖注入的相关功能。
  • SingletonBeanRegistry:提供了单例对象的注册管理的相关功能。
  • AliasRegistry:提供了别名的注册管理的相关功能。
  • BeanDefinitionRegistry:提供了BeanDefinition的注册管理的相关功能。
public class DefaultListableBeanFactory { // 依赖注入过程中,用于优先级比较 private Comparator<Object> dependencyComparator; // 用于依赖注入过程中解决候选问题 private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); // 根据类型依赖注入时,首先从这里获取依赖的属性值 private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16); // 根据构造器实例化Bean时所使用的策略(解决方法覆盖MethodOverrides问题,CglibSubclassingInstantiationStrategy使用了代理方法) private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy(); /************* 继承自AbstractAutowireCapableBeanFactory ****************/ // 是否允许单例循环依赖(其实就是是否允许Spring尽最大努力为我们解决循环依赖) private boolean allowCircularReferences = true; // 这里面的类型不会在自动装配时作为注入点 private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>(); // 当这里面的类型不需要自动装配 private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>(); // 用于获取参数名 private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); /************* 继承自AbstractBeanFactory ****************/ // 父工厂 private BeanFactory parentBeanFactory; // 保存自定义Scope private final Map<String, Scope> scopes = new LinkedHashMap<>(8); // 保存所有BeanPostProcessor扩展 private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>(); // 用来完成SpEL功能 private BeanExpressionResolver beanExpressionResolver; // 进行字符串处理,最常用的是占位符的替换 private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>(); // 用于将一个类型的对象转换为另一个类型的对象,此处的typeConverter可由用户定义,在Spring中该成员优先级很高 // 只有在该typeConverter为null的时候,才会使用SimpleTypeConverter或者BeanWrapperImpl来完成TypeConverter功能 private TypeConverter typeConverter; private ConversionService conversionService; private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4); // 注意,这里value值是个PropertyEditor子类型的Class对象,因为PropertyEditor并非线程安全的,所以在使用时才实例化 private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4); /************* 继承自DefaultSingletonBeanRegistry ****************/ // 三级缓存 // 一级缓存用于缓存已经初始化后的单例 // 三级缓存用于存放对象工厂(就是缓存实例化后发布的对象,但用一个工厂对它进行了包装,以保证从缓存获取Bean时会进行额外处理) // 二级缓存用于缓存三级缓存处理后的对象,可根据二级缓存中是否有值来确定创建过程中是否发生了循环依赖 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); } 

ApplicationContext

Spring框架核心讲解 为了便于观看,下面挑选了ApplicationContext主要的继承关系:
Spring框架核心讲解

  • AbstractApplicationContext:抽象方法,主要定义了refresh()方法模板
    • GenericApplicationContext:不可重复refreshBeanFactory,在构建时已经指定了beanFactory,通常用在基于注解的情况
      • AnnotationConfigApplicationContext:供非Web环境的SpringBoot使用
      • AnnotationConfigServletWebApplicationContext:供ServletWeb环境的SpringBoot使用
      • AnnotationConfigReactiveWebApplicationContext:供ReactiveWeb环境的SpringBoot使用
    • AbstractRefreshableApplicationContext:可重复refreshBeanFactory构建一个新的beanFactory,通常用在基于配置的情况
      • AbstractXmlApplicationContext:基于XML的配置
        • ClassPathXmlApplicationContext:
        • FileSystemXmlApplicationContext:
      • AbstractRefreshableWebApplicationContext:基于Web
        • XmlWebApplicationContext:供SpringMVC使用
public abstract class AbstractApplicationContext { // 环境 private ConfigurableEnvironment environment; // ResourcePatternResolver接口具有getResources(...)方法以及继承ResourceLoader的getResource(...)ResourceLoader // ApplicationContext实现了ResourcePatternResolver接口,其getResources(...)实际上是委托该成员来根据路径匹配多个资源的 // AbstractApplicationContext本身继承了DefaultResourceLoader,其getResource(...)方法就是由从DefaultResourceLoader继承的方法完成 private ResourcePatternResolver resourcePatternResolver; // ApplicationContext实现了Lifecycle接口,其功能实际上是委托该成员来完成的(LifecycleProcessor继承自Lifecycle) private LifecycleProcessor lifecycleProcessor; // ApplicationContext实现了MessageSource接口,其国际化功能实际上是委托该成员来完成的 private MessageSource messageSource; // ApplicationContext实现了ApplicationEventPublisher接口,其事件发布功能实际上是委托该成员来完成的 private ApplicationEventMulticaster applicationEventMulticaster; // 当进行手动注册时,注册的监听器会存放在applicationListeners中,而后面根据bean进行注册的时候会额外通过ApplicationListenerDetector将其注册到applicationListeners中 // 在第一次刷新预处理时,会将applicationListeners中的数据放入earlyApplicationListeners // 如果后面重新刷新,用earlyApplicationListeners中的数据替换applicationListeners,从而保证applicationListeners处于第一次刷新前的值 private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>(); private Set<ApplicationListener<?>> earlyApplicationListeners; // 在注册监听器之前,发布的事件会临时保存在该集合中,在注册监听器之后做的第一件事,就是将这些早期事件进行发布 private Set<ApplicationEvent> earlyApplicationEvents; // BeanFactory扩展 private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>(); } 

BeanDefinition

Spring框架核心讲解

  • BeanDefinition:定义了作为BeanDefinition的基本功能,主要由一系列的getter和setter方法组成。其继承的AttributeAccessor接口拥有get/set/removeAttribute方法(类似Map),所以BeanDefinition可以以键值对的方式任意扩展其属性,BeanMetadataElement接口的唯一方法getSource用来指明构建当前BeanDefinition的配置源。
  • AnnotatedBeanDefinition: 提供了方便访问注解的方法。用@Component注解构建BeanDefinition时,可以根据其getMetadata()方法返回的AnnotationMetadata对象,方便地获取类的元数据及其注解属性;用@Bean注解构建BeanDefinition时,可以根据其getFactoryMethodMetadata()方法返回的MethodMetadata对象,方便地获取方法元数据及其注解属性,也可以用如同@Component注解构建BeanDefinition的方式获取类的元数据及其注解属性。AnnotationMetadata与MethodMetadata都是AnnotatedTypeMetadata的子接口,该接口可以方便地访问注解的属性值。与Java原生注解不同,Spring的注解可以通过元注解来标识其他注解,从而构建出父子关系,Spring的子注解是能够被当做父注解处理的。
  • AbstractBeanDefinition:除了实现BeanDefinition的基本功能外,还做了一定的功能扩展,主要由代表各种意义的成员变量及其getter和setter组成。实际使用到的各种BeanDefinition基本上都是以AbstractBeanDefinition作为基类进行扩展的。
    • GenericBeanDefinition:通过XML配置的bean一般会被直接解析为此类BeanDefinition,与AbstractBeanDefinition相比多了一个parent属性。
    • ScannedGenericBeanDefinition:通过包扫描的方式扫描被 @Component(包括用@Component作为元注解的注解,如@Service、@Controller、@Configuration等)标记的类会被解析为此类BeanDefinition(不使用索引时)。
    • ConfigurationClassBeanDefinition:以 @Bean标记的方法会被解析为此类BeanDefinition。
    • AnnotatedGenericBeanDefinition:以AnnotatedBeanDefinitionReader.register(Class<?>…componentClasses) 方式直接将类解析为BeanDefinition进行注册时,这些类会被解析为此类BeanDefinition;在包扫描时,如果是通过索引进行的注册,那么也是使用此类BeanDefinition(很多博客认为被@Configuration标记的类会被解析为此类BeanDefinition,经过本座验证,此种说法纯属扯淡(至少在5.x版本后这种说法不成立))。
  • RootBeanDefinition:不存在parent的BeanDefinition。在早期只能通过XML方式配置bean时,带有parent属性的bean会被解析为ChildBeanDefinition,不带parent属性的bean会被解析为RootBeanDefinition,但现在它们都已经被GenericBeanDefinition所取代,ChildBeanDefinition已经不再被使用,而RootBeanDefinition通常只作为MergedBeanDefinition使用。AbstractBeanFactory的getMergedBeanDefinition(…)方法会根据继承关系,将指定ID的BeanDefinition与其祖先BeanDefinition合并得到一个最终等效的MergedBeanDefinition,而这个MergedBeanDefinition不会再有parent,因此该方法返回的是一个RootBeanDefinition(或者定义一个继承自RootBeanDefinition的子类MergedBeanDefinition来作为返回类型更好,但实际上Spring并没有定义MergedBeanDefinition类,而是直接使用了RootBeanDefinition)
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable { // bean的类型,可能是String类型的全类名,也可能是Class类型 private volatile Object beanClass; // 作用范围,默认只有单例和原型两种,但可以进行扩展 private String scope = SCOPE_DEFAULT; // 只有非抽象的BeanDefinition才能实例化,抽象BeanDefinition只能作为其他BeanDefinition的父BeanDefinition private boolean abstractFlag = false; // 单例是否懒加载(初始化时不实例化,使用时才实例化),BeanFactory都是在使用时实例化,ApplicationContext初始化时会实例化lanyInit为false的BeanDefinition private boolean lazyInit = false; // 自动装配模式AUTOWIRE_NO、AUTOWIRE_BY_NAME、AUTOWIRE_BY_TYPE、AUTOWIRE_CONSTRUCTOR(构造参数也是通过byType方式获取) // AUTOWIRE_CONSTRUCTOR也是通过byType方式获取构造器参数,AUTOWIRE_BY_NAME、AUTOWIRE_BY_TYPE实际上是通过setter来完成注入的 private int autowireMode = AUTOWIRE_NO; // 当前BeanDefinition被作为按类型注入到其他Bean时的候选时,如果该值为false,那么会将当前BeanDefinition从候选中删除 private boolean autowireCandidate = true; // 根据类型获取bean或根据类型依赖时,该属性为true的BeanDefinition为作为首选提供 private boolean primary = false; // 依赖注入过程中辅助Qualifier注解来完成候选者的筛选,一般key是Qualifier注解的类名(可以自定义Qualifier注解,不一定被@Qualifier标记) // 在使用某个Qualifier注解来筛选候选者时,根据注解的类名获取相应的AutowireCandidateQualifier来辅助Qualifier注解完成任务 // 实际应用中这是个空Map,所以没有起作用 private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(); // 是否进行依赖注入检查,是否所有非Integer等类型的属性都被依赖注入了,通常不需要检查 private int dependencyCheck = DEPENDENCY_CHECK_NONE; // dependsOn为一系列的bean的Id(或别名),创建当前Bean时必须先创建dependsOn对应的Bean private String[] dependsOn; // 是否允许非public的构造器及类被使用 private boolean nonPublicAccessAllowed = true; private boolean lenientConstructorResolution = true; // 如果该属性不为null,在实例化Bean时会首先通过instanceSupplier.get()得到实例化的Bean private Supplier<?> instanceSupplier; // 通过该属性作为name获取到的Bean是创建最终Bean的工厂 private String factoryBeanName; // 如果该属性不为null,那么这就是工厂方法 // 当factoryBeanName不为空时,通过factoryBeanName获取到Bean的工厂,并调用其成员方法factoryMethodName(...)得到实例化的Bean // 当factoryBeanName为空时,beanClass代表的类就是工厂,调用其静态方法factoryMethodName(...)得到实例化的Bean private String factoryMethodName; private ConstructorArgumentValues constructorArgumentValues; // 就像Map一样,存放属性-值的键值对,用于实例化后的属性注入 private MutablePropertyValues propertyValues; // 方法覆盖,MethodOverrides是抽象类MethodOverride的集合,MethodOverride有ReplaceOverride与LookupOverride两个子类 private MethodOverrides methodOverrides = new MethodOverrides(); // 初始化方法的名称 private String initMethodName; // 销毁方法的名称 private String destroyMethodName; // 如果找不到initMethodName方法,依然强制要求执行initMethodName方法时(enforceInitMethod为true),会抛出异常 private boolean enforceInitMethod = true; // 如果找不到destroyMethodName方法,依然强制要求执行destroyMethodName方法时(enforceDestroyMethod为true),会抛出异常 // 检查过程并非发生在执行destroyMethodName方法时,而是在获取Bean时,构建DisposableBeanAdapter的过程中 private boolean enforceDestroyMethod = true; // 当前BeanDefinition是否是虚构的,虚构的没有源码,而是由框架生成,它创建Bean的过程中不会执行初始化前后处理操作 private boolean synthetic = false; // 实际用处不大,可取BeanDefinition.ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE private int role = BeanDefinition.ROLE_APPLICATION; // 描述信息,无多大实用 private String description; // 不同来源的BeanDefinition该属性不同,如xml文件、Java类等 private Resource resource; } 

重要流程

BeanFactory

核心获取Bean:doGetBean(…)

根据beanName来获取相应的Bean,该过程提供了大量可扩展的钩子。

  • 获取未进行FactoryBean处理的Bean
    • 获取缓存的单例Bean
      • 单例缓存有三级缓存,其中第二级缓存从第三级缓存获取数据时,调用了SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(…)扩展
    • 如果不存在缓存的单例,就创建Bean(如果是单例,会将创建的Bean进行缓存,如果是自定义Scope会由自定义框架进行缓存)
      • 创建前预处理
        • 解决原型依赖
        • 如果当前容器无法创建(没有注册相应BeanDefinition),委托父容器创建
        • dependsOn处理
      • 实例化
        • 实例化前处理,如果实例化前处理返回了实例对象,那么经过初始化后处理就直接得到了最终未处理的Bean,InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(…)
        • 实例化(这不进行完会发布实例到三级缓存)
          • instanceSupplier实例化(优先级最高)
          • factoryMethod实例化(优先级次之)
          • 构造器实例化
            • SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(…)决定候选构造器
            • 根据候选构造器以及构造参数决定使用哪个构造器
            • 策略创建实例(主要是为了解决方法覆盖问题)
        • MergedBeanDefinition扩展,MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(…)
        • 发布实例的ObjectFactory到第三级缓存
        • 实例化后处理,InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(…)
      • 属性注入
        • 自动注入
        • 依赖注入扩展,InstantiationAwareBeanPostProcessor.postProcessProperties(…)
        • 依赖注入pvs
      • 初始化
        • 基本Aware处理(BeanNameAware、BeanClassLoaderAware和BeanFactoryAware处理)
        • 初始化前处理,BeanPostProcessor.postProcessBeforeInitialization(…)
        • 初始化
          • 如果当前Bean继承自InitializingBean,那么调用其afterPropertiesSet(…)方法
          • 如果当前BeanDefinition的initMethodName属性不为空,调用当前对象的该方法
        • 初始化后处理,BeanPostProcessor.postProcessAfterInitialization(…)
      • 销毁适配器的注册
        • DisposableBeanAdapter的注册(一个单例会对应一个DisposableBeanAdapter),对象在销毁时会调用DisposableBeanAdapter.destroy(…)方法
          • DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(…)(在创建DisposableBeanAdapter时,所有符合条件的DestructionAwareBeanPostProcessor都保存在了DisposableBeanAdapter中)
          • 如果当前Bean继承自DisposableBean,那么调用其destroy()方法
          • 调用BeanDefinition.destroyMethodName所代表的方法
    • 如果无法创建Bean(没有BeanDefinition),就委托父容器处理,当前容器后面的操作就被截断了
  • FactoryBean处理
  • 类型转换

封装获取Bean:getBean(…)

容器并没有将doGetBean(…)提供给容器使用者,而是对外提供了封装接口getBean(…)来获取Bean实例。带有name属性的getBean(…)方法直接调用了doGetBean(…)方法,而不带name属性的getBean(…)方法,先会通过类型获取相应的name,然后再调用doGetBean(…)方法来获取Bean实例。

  • 根据类型获取所有候选beanName(同类型或其子类、或一个封装类一个基本类)。如果希望获取的就是FactoryBean本身的类型,那么得到的候选时&beanName,如果希望获取的不是FactoryBean,但某个beanName对应的是FactoryBean且其getObjectType()返回值匹配,那么也返回其beanName作为候选
  • 如果有多个候选从中决定一个
    • 只保留不存在BeanDefinition的beanName(手动注册的单例),以及BeanDefinition.isAutowireCandidate()为true的
    • 如果候选依然大于1,选择BeanDefinition.primary属性为true的(多个满足抛异常)
    • 上一步未做出选择,那么选择priority值最大的候选(多个最大抛异常)
  • 决策出一个beanName就根据它获取Bean(doGetBean(…)),否则就委托父容器去处理

依赖获取:resolveDependency(…)

无论是BeanFactory的自动装配,还是扩展的@Autowired注解,最终都是通过该方法来获取到依赖的属性值的。

  • 处理特殊类型
    • Optional,通过泛型参数的类型来获取依赖属性值并封装为Optional
    • ObjectFactory、ObjectPrivider、javax.inject.Privider直接返回一个工厂,在通过工厂获取实例的过程中,会根据工厂的泛型参数类型来获取依赖属性值
  • 处理懒依赖
  • 获取依赖属性值
    • 从捷径获取(捷径缓存了beanName,直接通过beanName获取Bean)
    • 获取建议值
    • 数组、集合类型处理(获取候选并排序后放入数组、集合中)
    • 获取候选
      • resolvableDependecies中以及类型匹配的Bean
      • 去除自依赖以及并非候选的BeanDefinition
      • 如果上一步为空,那么放松泛型依赖检查
      • 如果上一步为空,那么放松自依赖检查
    • 从候选中做出选择(如果候选个数大于1)
      • BeanDefinition.primary属性为true的(多个满足抛异常)
      • priority值最大的候选(多个最大抛异常)
      • 来自resolvableDependecies或beanName为变量名的
    • 候选为空时需要检查是否允许为空,如果不允许则抛出异常

ApplicationContext

初始化上下文:refresh(…)

  • 初始化前的准备工作(主要是准备环境,初始化事件监听器)
  • 获取BeanFactory
  • 初始化BeanFactory前的准备工作
    • 设置工厂的BeanExpressionResolver为StandardBeanExpressionResolver
    • 注册一些与资源相关的属性编辑器(如File、URI、Resource等)
    • 扩展了一些感知接口ApplicationContextAwareProcessor
    • ApplicationListenerDetector扩展(实现了BeanPostProcessor接口),如果处理的Bean是ApplicationContext类型,那么将其注册
  • 预留postProcessBeanFactory(beanFactory)供子类实现
  • 执行BeanFactoryPostProcessor扩展
  • 注册BeanPostProcessor(所有实现了该接口的Bean都会进行注册)
  • 设置MessageSource(默认DelegatingMessageSource)
  • 设置广播器(默认SimpleApplicationEventMulticaster)
  • 预留onRefresh()供子类实现
  • 注册事件监听器并完成早期事件的广播(实现了ApplicationListener接口的Bean并不会在这里注册,在实例化的过程中通过ApplicationListenerDetector扩展进行注册,如非懒加载单例的实例化过程中,所以无法在实例化单例前监听到广播的事件)
  • 完成BeanFactory的初始化
    • 设置BeanFactory的ConversionService
    • 注册一个默认的StringValueResolver(处理方式为用环境变量替换${})
    • 将非抽象非懒加载的单例BeanDefinition进行实例化
  • 完成上下文初始化
    • 设置LifecycleProcessor(默认DefaultLifecycleProcessor,它会回调所有实现了Lifecycle的Bean的相应方法)
    • 通过LifecycleProcessor广播onRefresh
    • 发布ContextRefreshedEvent事件
  • 清空缓存

SpringMVC

初始化ContextLoaderListener

ContextLoaderListener继承自ContextLoader,而ContextLoader负责完成初始化功能(入口方法为initWebApplicationContext(…))。ContextLoaderListener还实现了ServletContextListener接口,以便利用Servlet容器启动时提供的钩子执行初始化代码(在contextInitialized(…)方法中直接调用了initWebApplicationContext(…))。

  • 创建WebApplicationContext(如果还没有WebApplicationContext)
    • 获取WebApplicationContext的具体类型(越靠前的优先级越高)
      • ServletContext中key为"contextClass"的参数对应的值就是具体类型的类全名
      • org/springframework/web/context/ContextLoader.properties中key为org.springframework.web.context.WebApplicationContext的值就是具体类型的类全名
    • 实例化
  • 配置与刷新
    • 设置Spring的配置资源(ServletContext中key为"contextConfigLocation"的参数)
    • 设置标准的Servlet环境
    • ApplicationContextInitializer初始化
      • 获取所有配置的ApplicationContextInitializer类型(ServletContext中key为"globalInitializerClasses"以及"contextInitializerClasses"的参数配置的类全名,多个用","、";" 或 "\t\n"分割)
      • 排序后依次调用它们的initialize(…)
    • 执行WebApplicationContext的refresh()方法
  • 发布WebApplicationContext(以ServletContext的attribute方式发布为root上下文)

初始化DispatherServlet

作为一个Servlet,其初始化入口是其init()方法。

  • 配置DispatcherServlet(根据ServletConfig的参数设置DispatherServlet中名相同的属性,这样就可以通过ServletConfig来设置DispatherServlet所有成员的值)
  • 获取WebApplicationContext
    • 已存在WebApplicationContext(成员变量webApplicationContext已有值)
      • 从ServletContext的attribute中获取root上下文作为父容器
      • 配置与刷新
        • 添加SourceFilteringListener监听器
        • 设置标准的Servlet环境
        • ApplicationContextInitializer初始化
          • 获取所有配置的ApplicationContextInitializer类型(ServletContext中key为"globalInitializerClasses"参数以及成员变量contextInitializerClasses配置的类全名,多个用","、";" 或 "\t\n"分割)
          • 排序后依次调用它们的initialize(…)
        • 刷新上下文
    • 获取已发布的WebApplicationContext(发布的位置在ServletContext的attribute中)
    • 创建WebApplicationContext(类型由成员变量contextClass决定,默认为XmlWebApplicationContext.class)
      • 从ServletContext的attribute中获取root上下文作为父容器
      • 设置Spring的配置资源(由成员变量contextConfigLocation决定)
      • 配置与刷新(同已存在WebApplicationContext的情况相同)
  • Web功能的初始化(九大Web组件的初始化,这些组件的初始化套路都是一样的,先从上下文中获取相应名称的Bean来初始化,如果未配置,则通过spring-webmvc包下org/springframework/web/servlet目录中的DispatcherServlet.properties配置来获取默认类型(实际上会将相应的实现类封装成原型模式的BeanDefinition,再获取Bean,这样获取Bean过程中的扩展就会生效))
    • MultipartResolver:它是一个例外,初始化时不会获取默认值
    • LocaleResolver:默认为AcceptHeaderLocaleResolver
    • ThemeResolver:默认为FixedThemeResolver
    • HandlerMapping:可多个,默认使用了BeanNameUrlHandlerMapping、RequestMappingHandlerMapping、RouterFunctionMapping
    • HandlerAdapter:可多个,默认使用了HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter、HandlerFunctionAdapter
    • HandlerExceptionResolver:可多个,默认使用了ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver
    • RequestToViewNameTranslator:默认为DefaultRequestToViewNameTranslator
    • ViewResolver:可多个,默认为InternalResourceViewResolver
    • FlashMapManager:默认为SessionFlashMapManager
  • 发布WebApplicationContext(发布的位置在ServletContext的attribute中)

请求处理过程

作为一个Servlet,其请求处理是其service(…)方法。

  • 非Option请求处理
    • 为请求线程创建一个线程上下文,用来存放线程独有的组件
      • 为线程上下文添加LocaleContext(使用了LocaleResolver组件)
      • 为线程上下文添加ServletRequestAttributes
    • 异步处理请求的支持
    • 重定向参数获取FlashMap
    • 请求处理
      • 如果是文件上传请求,将请求转换为MultipartHttpServletRequest类型
      • 根据请求获取处理链(一系列拦截器与一个处理器)
      • 获取一个能够适配处理器的适配器
      • 拦截器前置处理
      • 通过适配器来调用处理器,得到ModeAndView
      • 拦截器后置处理(倒置调用)
      • 将view写入响应
        • 如果请求处理过程中产生了异常,进行异常处理(如果是ModelAndViewDefiningException异常,该异常自带了ModeAndView,使用异常处理器处理异常,)
        • ModeAndView处理(异常时产生的ModeAndView或者适配器产生的ModeAndView)
          • 如果ModeAndView携带了viewName,通过ViewResolver来得到View
          • 如果ModeAndView没有携带viewName,看它是否已经携带了View
          • 通过View与Mode来渲染本次请求的响应
    • 发布ServletRequestHandledEvent事件
  • Option请求处理

SpringBoot

创建SpringApplication

  • 推断应用类型(根据类路径或jar包中是否存在某些类来推断)
  • 获取ApplicationContextInitializer与ApplicationListener(来源于META-INF/spring.factories配置文件)
  • 推断出主类(通过调用栈回溯到main函数所在的类)

运行SpringApplication

  • 配置Handless模式
  • 初始化SpringApplicationRunListeners
  • SpringApplicationRunListeners.starting()(广播ApplicationStartingEvent事件)
  • 准备运行环境
    • 根据应用类型创建不同类型的环境
    • 根据命令行参数创建PropertySource放入环境
    • SpringApplicationRunListeners.environmentPrepared(…)(广播ApplicationEnvironmentPreparedEvent事件)
  • 打印启动图形
  • 创建上下文,根据应用类型创建不同类型的上下文(如AnnotationConfigServletWebServerApplicationContext)
  • 获取异常报告器(这之后的异常便会进行异常报告了)
  • 配置上下文
    • 所有ApplicationContextInitializer的initialize(…)
    • SpringApplicationRunListeners.contextPrepared(…)(广播ApplicationContextInitializedEvent事件)
    • 注册LazyInitializationBeanFactoryPostProcessor
    • 加载source为BeanDefinition
    • SpringApplicationRunListeners.contextLoaded(…)(广播ApplicationPreparedEvent事件)
  • 刷新上下文
    • postProcessBeanFactory(…)
      • WebApplicationContextServletContextAwareProcessor
      • 注册application、request与session作用范围
      • ClassPathBeanDefinitionScanner.scan(this.basePackages)
      • AnnotatedBeanDefinitionReader.register(ClassUtils.toClassArray(this.annotatedClasses));
    • onRefresh()
      • 初始化ThemeSource
      • 创建Web服务器
  • 刷新后扩展(默认是空函数,由子类实现)
  • SpringApplicationRunListeners.started(…)(广播ApplicationStartedEvent事件)
  • 回调上下文中实现了ApplicationRunner和CommandLineRunner接口的Bean
  • SpringApplicationRunListeners.running(…)(广播ApplicationReadyEvent事件)

BeanDefinition解析

XmlBeanDefinitionReader

  • 将字符串解析为多个资源路径(如果资源加载器不是正则资源加载器时,只会得到一个资源路径)
  • 依次处理所有资源
    • 处理资源
      • 解决循环import
      • 用SAX将xml解析为Document委托给BeanDefinitionDocumentReader处理
        • 处理具有root特性的标签元素
          • 根据profile决定是否处理具有root特性的标签元素及其子元素
          • 根据标签是否是默认标签进行分支解析
            • 处理默认标签
              • import标签直接当做一个新的资源递归调用处理资源
              • beans标签作为一个具有root特效的标签元素递归处理
              • alias直接注册别名
              • bean解析为一个BeanDefinition
            • 处理自定义标签
              • 根据命名空间获取相应的处理器(META-INFO/spring.handlers配置命名空间和处理器的对应关系)
              • 根据处理器进行处理

AnnotatedBeanDefinitionReader

实例化

  • 初始化ConditionEvaluator
  • 注册最基本的用于注解功能的扩展
    • 对BeanFactory的一些成员进行设置
      • 设置优先级比较的实例AnnotationAwareOrderComparator
      • 设置依赖候选处理的实例为ContextAnnotationAutowireCandidateResolver
    • 注册一些扩展
      • ConfigurationClassPostProcessor
      • AutowiredAnnotationBeanPostProcessor
      • CommonAnnotationBeanPostProcessor(需要指出JSR-250,这与JRE版本有关)
      • PersistenceAnnotationBeanPostProcessor(前提是引入了jpa相关包才会注册)
      • EventListenerMethodProcessor与DefaultEventListenerFactory

注册:registerBean(…)

  • 创建BeanDefinition(AnnotatedGenericBeanDefinition类型)
  • 条件判断需要注册当前BeanDefinition(@Conditional),不需要就直接退出,不继续执行
  • 配置BeanDefinition
    • 获取并设置作用范围(解析@Scope注解)
    • 得到beanName(根据@Component等的value来得到)
    • 根据类上的注解设置BeanDefinition的属性(包括lazyInit、primary、dependsOn、role、description)
    • 自定义处理(处理由参数传入的BeanDefinitionCustomizer数组,依次调用customize(…)方法)
    • 处理scoped-proxy(创建一个BeanDefinition的代理可以解决此问题)
  • 注册BeanDefinition

ClassPathBeanDefinitionScanner

实例化

  • 设置默认的excludeFilters与includeFilters
  • 配置环境变量
  • 设置资源加载器

扫描:scan(…)

  • 扫描(所有需要扫描的包依次扫描)
    • 筛选出包中被@Component标记且符合@Conditional的类封装成BeanDefinition(ScannedGenericBeanDefinition类型)
    • 配置BeanDefinition(同AnnotatedBeanDefinitionReader解析过程中这一步相同)
  • 注册最基本的用于注解功能的扩展(同AnnotatedBeanDefinitionReader实例化过程中这一步相同)

本文地址:https://blog.csdn.net/oDiQiuTaiWeiXian/article/details/88779934

相关标签: Spring框架