【不懂】spring bean生命周期
完整的生命周期(牢记):
1.spring容器准备
2.实例化bean
3.注入依赖关系
4.初始化bean
5.使用bean
6.销毁bean
Bean的完整生命週期可以認為是從容器建立初始化Bean開始,直到Spring容器關閉。
事實上,在Bean被初始化建立之前,容器級別的介面方法也會對Bean產生影響,因此這裡把這兩個事件也加進來了。
各种接口方法分类
将上述流程分为三类:
1.Bean自身的方法,如Bean自身的构造函数、Setter方法设置属性以及<bean>的init-method和destroy-method所指定的初始化和销毁时的方法。
2.Bean级别生命周期接口方法,需要bean自身实现接口的方法,如BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean(例:如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID)
3.容器级别生命周期接口,即 后处理器 。此类一般不由Bean本身实现,独立于Bean,实现这些接口的类以容器附加装置的形式注册到Spring容器中。特点是:当Spring容器创建任何Bean的时候,这些后处理器都会执行并发生作用,它们的影响是全局性的。 如: InstantiationAwareBeanPostProcessor和BeanPostProcessor 接口。
后处理器在实例化bean的时候就实例化了,如BeanPostProcessor在实例化bean之前已经实例化,但在初始化bean的时候才被使用,见上图 区别:
第一类别,目标Bean关注自身方法,不需要实现任何接口。
第二类别,目标Bean需要实现相应的接口,有耦合。
第三类别,修改和目标Bean没有关系,需要额外的类实现接口,并注册到Spring容器中。
Spring框架中,一旦把一个Bean纳入Spring IOC容器之中,这个Bean的生命周期就会交由容器进行管理,一般担当管理角色的是BeanFactory或者ApplicationContext
如图,ApplicationContext继承自BeanFactory,因而提供BeanFactory所有的功能,除此之外还继承了其他接口,所以
1.MessageSource, 提供国际化的消息访问
2.资源访问,如URL和文件
3.事件传播
4.载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
1).BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。
2).BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册
图中步骤编号对应生命周期:
1.spring容器准备:图中未包含
2.实例化bean:1,2,3,4
3.注入依赖关系:5,6,7
4.初始化bean:8,9,10,11
5.使用bean:12
6.销毁bean:13,14
见上图,对于prototype作用域的Bean,Spring容器仅仅负责创建,当容器创建了Bean实例之后,Bean实例完全交给客户端代码管理,容器不再跟踪其生命周期。每次客户端请求prototype作用域的Bean时,Spring都会产生一个新的实例,Spring容器无法知道它曾经创造了多少个prototype作用域的Bean,也无从知道这些prototype作用域的Bean什么时候才会销毁。因此,Spring无法管理prototype作用域的Bean。
- 当调用者通过getBean(beanName)向容器请求某一个Bean时,如果容器中注册了 InstantiationAwareBeanPostProcessor接口,就会在实例化Bean之前,调用接口的postProcessBeforeInstantiation()方法。
- 根据配置情况调用Bean构造函数或工厂方法实例化Bean
- 调用postProcessAfterInstantiation()方法,对已经实例化的对象进行一些加工
- 如果Bean配置了属性信息,这一步将配置值设置到Bean对应的属性中,在设置每个属性之前将先调用postProcessPropertyValues()方法
- 调用Bean的属性设置方法设置属性
- 如果实现了BeanNameAware接口,将调用setBeanName()接口方法,将配置文件中该Bean对应的名称设置到Bean中
- 如果实现了BeanFactoryAware接口,通过setBeanFactory()方法,将BeanFactory()容器实例设置到Bean中
- 如果BeanFactory装配了BeanPostProcessor后处理器,将调用Object postProcessBeforeInitialization(Object bean,String beanName)接口方法对Bean进行加工操作。bean为当前正在处理的Bean,返回加工后的Bean。为容器提供对Bean进行后续加工处理的切入点,AOP,动态代理等功能都是通过BeanPostProcessor实施的。
- 如果Bean实现了InitializingBean接口,将调用接口的afterPropertiesSet()方法
- 执行<bean>中init-method属性定义的初始化方法
- BeanPostProcessor后处理器的 postProcessAfterInitialization再次对bean进行加工
- 如果scope='prototype',就返回bean给调用者,调用者负责bean后续生命的管理,Spring不再管理这个Bean的生命周期。如果作用范围是"singleton",Bean将放入SpringIoC容器缓存池中,并将bean引用返回,Spring继续对这些Bean进行后续的生命管理。
- 对于singleton的bean,容器关闭时会触发Spring对Bean后续生命周期的管理。如果Bean实现了DisposableBean接口,将调用接口的destory()方法,可以在此编写释放资源,记录日志等操作。(dispose处理)
- 调用<bean>的destroy-method属性指定的方法进行bean的销毁
Bean的完整生命周期从Spring容器实例化开始,直到最终销毁Bean。大致分为4类操作:
- Bean自身的方法:如调用Bean构造函数实例化Bean,调用Setter设置Bean的属性值及通过<bean>的init-method和destroy-method所指定的方法
- Bean级生命周期接口方法:BeanNameAware,BeanFactoryAware,InitializingBean和DisposableBean,接口方法由Bean类直接实现
- 容器级生命周期接口:InstantiationAwareBeanPostProcesser和BeanPostProcessor这两个接口实现,一般称为"后处理器"。实现类以容器附加装置的形式注册到Spring容器中,通过接口反射为Spring容器扫描识别。Spring容器创建任何Bean时,这些后处理器都会发生作用,影响是全局性的。
- 工厂后处理器接口方法:AspectJWeavingEnabler,CustomAutowireConfigurer,ConfigurationClassPostProcessor等方法。容器级,在应用上下文装配配置文件后立即调用。
ResourceLoader resourceLoader = new PathMatchingResourcePatternResolver();
Resource resource = resourceLoader.getResource("classpath:spring/SpringContext.xml"); BeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader((DefaultListableBeanFactory) beanFactory);
reader.loadBeanDefinitions(resource); //向容器中注册BeanPostProcessor后处理器
((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
((ConfigurableBeanFactory) beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor()); Car car = (Car) beanFactory.getBean("car");
Car car1 = (Car) beanFactory.getBean("car");
System.out.println(car == car1);//默认单例,两次获取的car对象一样
car.carRun(); //关闭容器
((DefaultListableBeanFactory) beanFactory).destroySingletons();
在对beanfactory注册BeanPostProcessor后处理器时,将beanfactory强制类型转换为了ConfigurableBeanFactory。由于addBeanPostProcessor()方法是在ConfigurableBeanFactory接口中定义的。多个后处理器注册时,实际调用顺序和注册顺序无关,多后处理器需要实现Ordered接口。上面获取了两次car对象,如果是prototype范围,则生命周期会被执行两次,因为每次都返回的新对象实例。思考:通过Bean级别的生命周期接口对Bean进行控制,虽然让Bean具有了更细致的生命周期阶段,但是让Bean和Spring框架紧密结合在一起了。通常通过init-method和destroy-method属性配置的方式来为Bean指定初始化和销毁的方法。Spring还提供了一个Bean后置处理器,InitDestroyAnnotationBeanPostProcessor.负责对标注了@PostConstruct,@PreDestroy的Bean进行处理,在bean初始化后及销毁前执行相应的逻辑(在ApplicationContext中,已经默认装配了该处理器)。如果bean希望在运行期获知在配置文件中的Bean名称,可以简单地将名称作为属性注入BeanProcessor接口十分特殊,它不要求Bean去继承,可以完全像插件一样注册到Spring容器中。AOP等功能就是基于此实现的。
ApplicationContext中Bean的生命周期
Bean在应用上下文中的生命周期和在BeanFactory中的生命周期类似,不同的是,如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会增加一个调用方法setApplicationContext()的步骤。
如果配置文件中声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,在初始化Bean实例之前会调用这些BeanFactoryPostProcessor对配置信息进行加工处理。Spring框架提供了多个工厂后处理器,CustomEditorConfigurer,PopertyPlaceholderConfigurer等。
(总结:)
初始化阶段,先调用 InitializingBean接口的afterPropertiesSet()方法,再调用init-method属性定义的初始化方法。与销毁阶段不同的是,初始化阶段外面包裹了一层BeanPostProcessor后处理器的postProcessBeforeInitialization()和postProcessAfterInitialization()方法
销毁阶段,先调用 DisposableBean接口的destory()方法,再调用destory-method属性定义的销毁方法
BeanFactory和ApplicationContext区别就在于BeanFactory手动注册:
ApplicationContext会利用Java反射机制自动识别出配置文件中定义的BeanPostProcesser,InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中。而BeanFactory需要手动addBeanPostProcessor()去进行注册。
调用ApplicationContextAware
接口的setApplicationContext()
方法,传入该Bean
的ApplicationContext
,这样该Bean
就获得了自己所在的ApplicationContext,不用再手动注册了
ApplicationContext Bean生命周期流程
流程

【不懂】spring bean生命周期的更多相关文章
- spring bean 生命周期和 ? 作用域? spirng bean 相互依赖? jvm oom ? jvm 监控工具? ThreadLocal 原理
1. spring bean 生命周期 1. 实例化一个bean ,即new 2. 初始化bean 的属性 3. 如果实现接口 BeanNameAware ,调用 setBeanName 4. Bea ...
- Spring点滴四:Spring Bean生命周期
Spring Bean 生命周期示意图: 了解Spring的生命周期非常重要,我们可以利用Spring机制来定制Bean的实例化过程. -------------------------------- ...
- Spring Bean 生命周期之destroy——终极信仰
上一篇文章 Spring Bean 生命周期之我从哪里来 说明了我是谁? 和 我从哪里来? 的两大哲学问题,今天我们要讨论一下终极哲学我要到哪里去? 初始化 Spring Bean 有三种方式: @P ...
- 常见问题:Web/Servlet生命周期与Spring Bean生命周期
Servlet生命周期 init()初始化阶段 Servlet容器加载Servlet(web.xml中有load-on-startup=1;Servlet容器启动后用户首次向Servlet发请求;Se ...
- 大厂高频面试题Spring Bean生命周期最详解
Spring作为当前Java最流行.最强大的轻量级框架.Spring Bean的生命周期也是面试高频题,了解Spring Bean周期也能更好地帮助我们解决日常开发中的问题.程序员应该都知道Sprin ...
- Spring Bean生命周期,好像人的一生。。
大家好,我是老三,上节我们手撸了一个简单的IOC容器五分钟,手撸一个Spring容器!,这节我们来看一看Spring中Bean的生命周期,我发现,和人的一生真的很像. 简单说说IoC和Bean IoC ...
- 睡前聊一聊"spring bean 生命周期"
spring bean 生命周期=实属初销+2个常见接口+3个Aware型接口+2个生命周期接口 实属初销:spring bean生命周期只有四个阶段,即实例化->属性赋值->初始化-&g ...
- Spring Bean 生命周期2
在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Sin ...
- Spring bean 生命周期验证
一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware s ...
随机推荐
- Gym - 101848C Object-Oriented Programming (树链剖分+线段树+动态开点)
C. Object-Oriented Programming time limit per test 3.0 s memory limit per test 1024 MB input standar ...
- 网络流相关知识点以及题目//POJ1273 POJ 3436 POJ2112 POJ 1149
首先来认识一下网络流中最大流的问题 给定一个有向图G=(V,E),把图中的边看做成管道,边权看做成每根管道能通过的最大流量(容量),给定源点s和汇点t,在源点有一个水源,在汇点有一个蓄水池,问s-t的 ...
- 利用SSH上传、下载(使用sz与rz命令)
安装yum -y install lrzsz 用法sz用法:从服务器发送出去相当于下载一个文件sz filename 下载多个文件sz filename1 filename2rz用法:从外面接收回来, ...
- UOJ277【清华集训2016】定向越野(计算几何,最短路)
UOJ题目传送门 显然最优的路径只会经过若干条两个圆的公切线和若干段圆弧 为了方便,把起点终点看成两个半径为\(0\)的圆也行. 最烦的就是算两个圆的公切线了,一共有四条 对于靠外面的两条,我们把切线 ...
- Coding and Paper Letter(五十八)
资源整理. 1 Coding: 1.支持TMS.WMTS标准瓦片下载,支持百度地图瓦片.高德地图瓦片.腾讯地图瓦片.天地图.ArcServer Rest瓦片.ArcServer本地缓存切片.geose ...
- Hdoj 2084.数塔 题解
Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大 ...
- 如何查看Linux操作系统版本?
参考地址:http://www.ggat.cn/newsInfo.html/71 如何查看Linux操作系统版本? 1. 查看内核版本命令: $ cat /proc/version $ uname - ...
- [SCOI2015]国旗计划[Wf2014]Surveillance
[SCOI2015]国旗计划 A国正在开展一项伟大的计划——国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这 项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了N名 ...
- 解决关于confluence缓慢 字体乱码 宏乱码 编辑不能贴图等问题
应用场景:Confluence软件不用多说,与Jira一样,都是atlassion的精品软件,不再介绍. 这里因为使用的是破解版的confluence,故遇见一些问题,只能百度谷歌自行解决,也在此记录 ...
- 如何在Windows 10上运行Docker和Kubernetes?
如何在Windows 10上运行Docker和Kubernetes? 在Windows上学习Docker和Kubernetes,开始的时候会让你觉得无从下手.最起码安装好这些软件都不是一件容易的事情. ...