Spring 基础
Bean 的 Scope
Spring 支持如下5种作用域:
- singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
- prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
- request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
- session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
- globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效
Bean 的生命周期
Spring 将 bean 的生命周期定义为实例化、属性填充、初始化和销毁四个阶段,并为每个阶段提供了多个拓展点用于自定义 bean 的创建过程。
实例化
创建 bean 对象实例的过程,包括使用工厂模式创建和调用构造函数。Spring 通过 InstantiationAwareBeanPostProcessor
接口在实例化前和后各提供了两个通用拓展点,加上对象实例化的过程,执行顺序如下:
postProcessBeforeInstantiation
:在普通 bean 对象实例化开始之前调用- 对象实例化
postProcessAfterInstantiation
:在普通 bean 对象实例化完成之后调用
属性填充
如果对象中有 setter 函数,并通过配置元数据指定了注入的属性,Spring 容器会在这一步为其注入配置的值。完成属性填充后,Spring 通过 Aware(意为感知) 接口提供了十个专用拓展点,这些拓展点用于在 bean 自身内部、感知信息和属性校验使用,执行顺序如下(注意下方列表是第零条是 Bean 属性填充,所以此处一共有十个拓展点):
- Bean 属性填充
- BeanNameAware#setBeanName
- BeanClassLoaderAware#setBeanClassLoader
- BeanFactoryAware#setBeanFactory
- EnvironmentAware#setEnvironment
- EmbeddedValueResolverAware#setEmbeddedValueResolver
- ResourceLoaderAware#setResourceLoader(仅在 ApplicationContext 中有效)
- ApplicationEventPublisherAware#setApplicationEventPublisher(仅在 - ApplicationContext 中有效)
- MessageSourceAware#setMessageSource(仅在 ApplicationContext 中有效)
- ApplicationContextAware#setApplicationContext(仅在 ApplicationContext 中有效)
- ServletContextAware#setServletContext(仅在 WebApplicationContext 中有效)
第一至第三个拓展点用于感知与 Bean 自身相关的信息、称之为 Bean 信息拓展点,第四至第八个拓展点统称为外部信息拓展点,随后第九第十两个拓展点与 ApplicationContext 有关。
初始化
初始化是指通过 bean 在将要工作前进行的最后准备工作,通常是 @Bean 的initMethod 属性定义的函数执行的过程 。Spring 通过 BeanPostProcessor 接口在初始化之前和之后提供了两个通用拓展点,加上 InitializingBean#afterPropertiesSet 和初始化函数执行顺序为:
- postProcessBeforeInitialization
- InitializingBean#afterPropertiesSet
- 自定义的初始化函数
- postProcessAfterInitialization
销毁
销毁是指 bean 释放其占用的一些外部资源的过程,通常是 @Bean 注解的 destroyMethod 属性定义的销毁函数执行的过程。Spring 通过 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction 接口提供了通用拓展点,再加上 DisposableBean#destroy 提供的专用拓展点,三者执行顺序为:
- DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
- DisposableBean#destroy
- 自定义的销毁函数。