概述
容器功能是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实例化过程中这一步相同)