Spring框架核心讲解
概述
容器功能是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,它定义了最基本的容器功能,即通过容器获取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使用
-
AbstractXmlApplicationContext:基于XML的配置
-
GenericApplicationContext:不可重复refreshBeanFactory,在构建时已经指定了beanFactory,通常用在基于注解的情况
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所代表的方法
-
DisposableBeanAdapter的注册(一个单例会对应一个DisposableBeanAdapter),对象在销毁时会调用DisposableBeanAdapter.destroy(…)方法
-
创建前预处理
- 如果无法创建Bean(没有BeanDefinition),就委托父容器处理,当前容器后面的操作就被截断了
-
获取缓存的单例Bean
- 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的值就是具体类型的类全名
- 实例化
-
获取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的情况相同)
-
已存在WebApplicationContext(成员变量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服务器
-
postProcessBeanFactory(…)
- 刷新后扩展(默认是空函数,由子类实现)
- 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配置命名空间和处理器的对应关系)
- 根据处理器进行处理
-
处理默认标签
-
处理具有root特性的标签元素
-
处理资源
AnnotatedBeanDefinitionReader
实例化
- 初始化ConditionEvaluator
-
注册最基本的用于注解功能的扩展
-
对BeanFactory的一些成员进行设置
- 设置优先级比较的实例AnnotationAwareOrderComparator
- 设置依赖候选处理的实例为ContextAnnotationAutowireCandidateResolver
-
注册一些扩展
- ConfigurationClassPostProcessor
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor(需要指出JSR-250,这与JRE版本有关)
- PersistenceAnnotationBeanPostProcessor(前提是引入了jpa相关包才会注册)
- EventListenerMethodProcessor与DefaultEventListenerFactory
-
对BeanFactory的一些成员进行设置
注册: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
推荐阅读
-
Python单元测试框架unittest使用方法讲解
-
SpringBoot 源码解析 (七)----- Spring Boot的核心能力 - SpringBoot如何实现SpringMvc的?
-
SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)
-
h5开发app用什么框架(h5开发app框架讲解)
-
Spring整合多数据源实现动态切换的实例讲解
-
Spring+Hibernate+Struts(SSH)框架整合实战
-
IOS框架Spring常用的动画效果
-
Spring框架学习笔记(3)——SpringMVC框架
-
深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议
-
Spring源码剖析1:初探Spring IOC核心流程