当前位置: 移动技术网 > IT编程>开发语言>Java > Spring框架核心讲解

Spring框架核心讲解

2020年08月01日  | 移动技术网IT编程  | 我要评论
文章目录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

BeanFactory继承关系

  • 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

为了便于观看,下面挑选了ApplicationContext主要的继承关系:
在这里插入图片描述

  • 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

在这里插入图片描述

  • 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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网