spring bean的init、destory的几种方法及生命周期
个人总结spring-bean的声明周期维护有三种:
- 注解:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
- xml中配置:xml中定义init-method和destory-method方法
- 接口继承:通过bean实现InitializingBean和DisposableBean接口
任何一个事物都有自己的生命周期,生命的开始、生命中、生命结束。大家最熟悉的应该是servlet 的生命周期吧。和 servlet 一样 spring bean 也有自己的生命周期。
实现Aware接口
Spring提供了一组Aware接口是针对某个实现这些接口的Bean定制初始化的过程,为了让Bean可以获取到框架自身的一些对象。 这些接口均继承于org.springframework.beans.factory.Aware
标记接口,并提供一个将由Bean实现的set*方法,Spring通过基于setter的依赖注入方式使相应的对象可以被Bean使用。
ApplicationContextAware | 获得ApplicationContext对象 |
BeanFactoryAware | 获得BeanFactory对象,可以用来检测Bean的作用域 |
BeanNameAware | 获得Bean在配置文件中定义的名字 |
ResourceLoaderAware | 获得ResourceLoader对象,可以获得classpath中某个文件 |
ServletContextAware | 可以获取ServletContext对象,可以读取context中的参数 |
ServletConfigAware | 可以获取ServletConfig对象,可以读取config中的参数 |
public class GiraffeService implements ApplicationContextAware, ApplicationEventPublisherAware, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, EnvironmentAware, ImportAware, ResourceLoaderAware{public void setBeanClassLoader(ClassLoader classLoader) {System.out.println("执行setBeanClassLoader,ClassLoader Name = " + classLoader.getClass().getName());}public void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("执行setBeanFactory,setBeanFactory:: giraffe bean singleton=" + beanFactory.isSingleton("giraffeService"));}public void setBeanName(String s) {System.out.println("执行setBeanName:: Bean Name defined in context="+ s);}public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("执行setApplicationContext:: Bean Definition Names="+ Arrays.toString(applicationContext.getBeanDefinitionNames()));}public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {System.out.println("执行setApplicationEventPublisher");}public void setEnvironment(Environment environment) {System.out.println("执行setEnvironment");}public void setResourceLoader(ResourceLoader resourceLoader) {Resource resource = resourceLoader.getResource("classpath:spring-beans.xml");System.out.println("执行setResourceLoader:: Resource File Name="+ resource.getFilename());}public void setImportMetadata(AnnotationMetadata annotationMetadata) {System.out.println("执行setImportMetadata");}
}
BeanPostProcessor
除Aware接口之外,Spring同样可以针对容器中的所有Bean或者某些Bean定制初始化过程,只需提供一个实现BeanPostProcessor接口的类即可(下面会重点讲)。
Spring Bean的生命周期
Bean生命周期是这样的:
- Bean容器找到配置文件中Spring Bean的定义。
- Bean容器利用Java Reflection API创建一个Bean的实例。
- 如果涉及到一些属性值 利用set方法设置一些属性值。
- 如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。
- 如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
- 如果Bean实现了BeanFactoryAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
- 与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。
- 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法
- 如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
- 如果Bean在配置文件中的定义包含
init-method
属性,执行指定的方法。 - 如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessAfterInitialization()方法
- 当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。
- 当要销毁Bean的时候,如果Bean在配置文件中的定义包含
destroy-method
属性,执行指定的方法
BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor和BeanPostProcessor
spring注释中经常提到“regular bean” 就是一个未实例化的bean,它就是BeanDefinition(bean metadata 信息),一个类被读取之后就是BeanDefinition,在被注册Ioc容器完毕以后,Spring Bean 工厂就可以随时根据需要进行实例化。对于XmlBeanFactory 来说,实例化默认是延迟进行的,也就是说在 getBean 的时候才会;而对于 ApplicationContext来说,实例化会在容器启动后通过 AbstractApplicationContext 中 reflash 方法自动进行。spring默认beanFactory为DefaultListableBeanFactory,可以从中得到证实。
BeanPostProcessor:bean级别的处理,针对某个具体的bean实例化后,初始化方法执行前(init-method或者实现了InitializingBean的afterPropertiesSet方法)。
- ApplicationContextAwareProcessor,处理EnvironmentAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware中对应的方法
- InstantiationAwareBeanPostProcessor拓展了BeanPostProcessors接口,这个接口也是非常的牛掰,可以在实例化Bean前(调用postProcessBeforeInstantiation方法)、后(调用postProcessAfterInstantiation)提供扩展的回调接口。
- SmartInstantiationAwareBeanPostProcessor,拓展了InstantiationAwareBeanPostProcessor接口,主要是供spring内部使用,提供有:predictBeanType(用来返回目标对象的类型)、determineCandidateConstructors(获取用来实例化的构造器)、getEarlyBeanReference(提前暴露bean引用,解决循环依赖)
- MergedBeanDefinitionPostProcessor,也是实例化后执行,主要缓存一些meta信息提供给后续的injectValue使用
- DestructionAwareBeanPostProcessor,是对象销毁的前置回调
BeanFactoryPostProcessor:BeanFactory级别的处理,是针对整个工厂中的bean作出修改或者新注册(包括BeanDefinition)。
- ServletComponentRegisteringPostProcessor,applicationContext如果是WebApplicationContext,注入ServletRegistrationBean。
BeanDefinitionRegistryPostProcessor,BeanFactory级别的处理,感觉比BeanFactoryPostProcessor 的语义环境更加强调BeanDefinition的个性化调整。
- ConfigurationClassPostProcessor,说实话个人感觉BeanFactoryPostProcessor更适合它的语义。
执行顺序:
1. 执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
- BeanDefinitionRegistryPostProcessor+PriorityOrdered
- BeanDefinitionRegistryPostProcessor+Ordered
- 剩余BeanDefinitionRegistryPostProcessor
2. 执行BeanFactoryPostProcessor的postProcessBeanFactory方法(与1中排序相同)
BeanDefinitionRegistryPostProcessor执行顺序先与BeanFactoryPostProcessor。
@FunctionalInterface
public interface BeanFactoryPostProcessor {//可以从factory中获取:BeanDefinition getBeanDefinition(String var1)void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
参阅资料
- life cycle management of a spring bean
- Spring Bean Life Cycle
spring bean的init、destory的几种方法及生命周期相关推荐
- spring bean实现init/destory生命周期方法的三种方式
实现InitializingBean和DisposableBean接口,实现afterPropertiesSet()和destroy()方法 使用@PostConstruct和@PreDestroy进 ...
- Spring框架学习day_01: 框架配置方式/ 管理对象的作用域/ 生命周期/ 组件扫描/ 单例模式:“懒汉式“,“饿汉式“
1. Spring框架的作用 Spring框架的主要作用是创建对象和管理对象. 创建对象:类似于User user = new User(); 管理对象:随时可以通过Spring框架获取对象,甚至Sp ...
- Bean的生命周期行为控制,初始化与销毁bean时执行操作的三种方法
Bean的生命周期行为控制,初始化与销毁bean时执行操作的三种方法 一.实现Spring的接口 二.XML配置中使用 init-method和destory-method 三.使用@PostCons ...
- Spring系列之集成MongoDB的2种方法,你知道嘛?
Spring系列之集成MongoDB的2种方法,你知道嘛? MongoDB是最流行的NoSQL数据库,SpringBoot是使用Spring的最佳实践.今天带大家讲一讲SpringBoot集成Mong ...
- java定时调度main方法_java相关:Spring中实现定时调度的几种方法
java相关:Spring中实现定时调度的几种方法 发布于 2020-11-28| 复制链接 本篇文章主要介绍了Spring中实现定时调度示例,可以在无人值守的时候系统可以在某一时刻执行某些特定的功能 ...
- Spring Boot 优雅停止服务的几种方法
作者 | 黄青石 来源 | https://www.cnblogs.com/huangqingshi/p/11370291.html 最近突然想到了优雅停止 SpringBoot 服务问题,在使用 S ...
- eclipse创建springboot项目_创建一个 Spring Boot 项目,你会几种方法?
我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 42W+,如下图: 2017 年由于种种原因,就没有 ...
- Spring(二)scope、集合注入、自动装配、生命周期
原文链接:http://www.orlion.ga/189/ 一.scope bean的scope属性中常用的有两种:singleton(单例,默认)和prototype(原型,每次创建新对象) 例: ...
- 超全面!8 种互联网常用生命周期完整指南~
什么是生命周期? 百度给出的定义是:生命周期就是指一个对象的生老病死. 生命周期的概念应用很广泛,特别是在政治.经济.环境.技术.社会等诸多领域经常出现,其基本涵义可以通俗地理解为"从摇篮到 ...
最新文章
- python最新版本-最新版Python 3.8.6 版本发布
- centos6.5环境 安装php5.5.30的redis扩展 介绍
- 【Groovy】Groovy 动态语言特性 ( Groovy 中的变量自动类型推断以及动态调用 | Java 中必须为变量指定其类型 )
- c语言入门后怎么玩,玩编程如何让人傻并快乐着?
- CRM WebClient UI和Hybris里工作中心跳转的url生成逻辑
- LintCode MySQL 1921. 从不充值的玩家(where not in)
- 听说你还不懂面向对象??
- 开发人员生产力指南,细节决定成败!
- 使用Visual Studio来创建动态库/静态库,并加载
- 【bzoj5166】[HAOI2014]遥感监测 贪心
- VS2008 SP1 安装卡在 VS90sp1-KB945140-X86-CHS的解决方法
- 3V升压5V芯片,3V升压5V的电路图
- r语言如何计算t分布临界值_R语言使用蒙特卡洛模拟进行正态性检验及可视化
- bi 工具 市场排行榜_现在市场上的主流BI工具有哪几个
- shell一站式攻略——history历史命令
- 【论文笔记】ARBITRAR: User-Guided API Misuse Detection
- 软件测试实验过程记录
- excel数字点一下才变为数值的批量快捷操作
- vue-element-admin 花裤衩 模板 ,中文版,运行报错解决方案
- Flutter--Hero组件