个人总结spring-bean的声明周期维护有三种:

  1. 注解:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
  2. xml中配置:xml中定义init-method和destory-method方法
  3. 接口继承:通过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的几种方法及生命周期相关推荐

  1. spring bean实现init/destory生命周期方法的三种方式

    实现InitializingBean和DisposableBean接口,实现afterPropertiesSet()和destroy()方法 使用@PostConstruct和@PreDestroy进 ...

  2. Spring框架学习day_01: 框架配置方式/ 管理对象的作用域/ 生命周期/ 组件扫描/ 单例模式:“懒汉式“,“饿汉式“

    1. Spring框架的作用 Spring框架的主要作用是创建对象和管理对象. 创建对象:类似于User user = new User(); 管理对象:随时可以通过Spring框架获取对象,甚至Sp ...

  3. Bean的生命周期行为控制,初始化与销毁bean时执行操作的三种方法

    Bean的生命周期行为控制,初始化与销毁bean时执行操作的三种方法 一.实现Spring的接口 二.XML配置中使用 init-method和destory-method 三.使用@PostCons ...

  4. Spring系列之集成MongoDB的2种方法,你知道嘛?

    Spring系列之集成MongoDB的2种方法,你知道嘛? MongoDB是最流行的NoSQL数据库,SpringBoot是使用Spring的最佳实践.今天带大家讲一讲SpringBoot集成Mong ...

  5. java定时调度main方法_java相关:Spring中实现定时调度的几种方法

    java相关:Spring中实现定时调度的几种方法 发布于 2020-11-28| 复制链接 本篇文章主要介绍了Spring中实现定时调度示例,可以在无人值守的时候系统可以在某一时刻执行某些特定的功能 ...

  6. Spring Boot 优雅停止服务的几种方法

    作者 | 黄青石 来源 | https://www.cnblogs.com/huangqingshi/p/11370291.html 最近突然想到了优雅停止 SpringBoot 服务问题,在使用 S ...

  7. eclipse创建springboot项目_创建一个 Spring Boot 项目,你会几种方法?

    我最早是 2016 年底开始写 Spring Boot 相关的博客,当时使用的版本还是 1.4.x ,文章发表在 CSDN 上,阅读量最大的一篇有 42W+,如下图: 2017 年由于种种原因,就没有 ...

  8. Spring(二)scope、集合注入、自动装配、生命周期

    原文链接:http://www.orlion.ga/189/ 一.scope bean的scope属性中常用的有两种:singleton(单例,默认)和prototype(原型,每次创建新对象) 例: ...

  9. 超全面!8 种互联网常用生命周期完整指南~

    什么是生命周期? 百度给出的定义是:生命周期就是指一个对象的生老病死. 生命周期的概念应用很广泛,特别是在政治.经济.环境.技术.社会等诸多领域经常出现,其基本涵义可以通俗地理解为"从摇篮到 ...

最新文章

  1. python最新版本-最新版Python 3.8.6 版本发布
  2. centos6.5环境 安装php5.5.30的redis扩展 介绍
  3. 【Groovy】Groovy 动态语言特性 ( Groovy 中的变量自动类型推断以及动态调用 | Java 中必须为变量指定其类型 )
  4. c语言入门后怎么玩,玩编程如何让人傻并快乐着?
  5. CRM WebClient UI和Hybris里工作中心跳转的url生成逻辑
  6. LintCode MySQL 1921. 从不充值的玩家(where not in)
  7. 听说你还不懂面向对象??
  8. 开发人员生产力指南,细节决定成败!
  9. 使用Visual Studio来创建动态库/静态库,并加载
  10. 【bzoj5166】[HAOI2014]遥感监测 贪心
  11. VS2008 SP1 安装卡在 VS90sp1-KB945140-X86-CHS的解决方法
  12. 3V升压5V芯片,3V升压5V的电路图
  13. r语言如何计算t分布临界值_R语言使用蒙特卡洛模拟进行正态性检验及可视化
  14. bi 工具 市场排行榜_现在市场上的主流BI工具有哪几个
  15. shell一站式攻略——history历史命令
  16. 【论文笔记】ARBITRAR: User-Guided API Misuse Detection
  17. 软件测试实验过程记录
  18. excel数字点一下才变为数值的批量快捷操作
  19. vue-element-admin 花裤衩 模板 ,中文版,运行报错解决方案
  20. Flutter--Hero组件

热门文章

  1. VUE 获奖名单滚动显示的两种方式
  2. workers.properties配置详解
  3. QT 中英文切换-国际化(解决部分翻译不起作用的问题)
  4. python批量修改字典的键或值
  5. Springboot学习1——通过JPA访问MySQL数据库
  6. Zookeeper和Kafka环境搭建总结
  7. iis服务器里网站无法访问,IIS服务器网站无法访问解决方法(图文).doc
  8. 基层管理者的角色定位
  9. 计算机网络实习内容,计算机网络工程实习目的与内容
  10. -2岁的产品经理学习日记2020/2/15