Spring 之bean的生命周期
今天我们来聊一下Spring Bean的生命周期,这是一个非常重要的问题,Spring Bean的生命周期也是比较复杂的。
IOC
IOC,控制反转概念需要提前了解一下,简单说就是把new对象的权利交给容器,所有的对象都由容器控制,称为控制反转
然后再通过依赖注入把它依赖的类注入给它。
Bean的生命周期
首先我们先来了解一下bean的作用域有哪些?
singleton: 在Spring IOC仅存在一个Bean实例,是Spring默认的bean作用域
prototype: 每次请求都会创建一个新的bean实例,即允许IOC中存在多个bean实例
request: 每次HTTP请求都会产生一个bean,该bean仅在HTTP request内有效
session:每一次HTTP请求都会产生一个新的bean,该bean在这个Session中共享
application:限定Bean的作用域为ServletContext的生命周期,该作用域仅适用于web的Spring WebApplicationContext环境
websocket: 限定Bean的作用域为WebSocket,该作用域仅适用于web的Spring WebApplicationContext环境
在Spring 中Bean的生命周期大致可以概况为:
实例化 -> 属性赋值 -> 初始化 -> 销毁
在Spring的Bean的生命周期种提供了很多的扩展点,常见的扩展接口有 InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware,InstantiationAwareBeanPostProcessor,BeanPostProcessor
其中的生命周期可以简单写为以下四步
实例化:首先,实例化一个Bean对象
属性赋值:为Bean对象设置属性和依赖
初始化:初始化,在完成后就可以被使用了
销毁:可以i通过第4步两种方法来添加配置
其中Bean的大致流程如图所示,展示了初始后的前置和后置过程,在实例化过程中也区分前置和后置过程,而初始化的前置和后置过程中主要是通过重写BeanPostProcessor中的postProcessBeforeInitialization和postProcessAfterInitialization实现的,销毁和初始也支持用户自定义方法。

下面我们继续来看在实例化和初始化时可以扩展的前置方法和后置方法。

运行结果

实例演示
实体类
public class User implements InitializingBean, BeanNameAware, DisposableBean, ApplicationContextAware {
private String name;
public User() {
System.out.println("1.2 User的无参构造, 实例化");
}
/**
* 初始化方法
*/
public void initMethod() {
System.out.println("3.3. bean对象的初始化,调用指定的初始化方法");
}
/**
* 销毁方法
*/
public void destroyMethod() {
System.out.println("4.2 bean对象的销毁,调用指定的销毁方法");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("2.1 设置User.name属性 设置属性");
this.name = name;
}
@Override
public void setBeanName(String name) {
System.out.println("2.2调用BeanNameAware.setBeanName()方法");
}
@Override
public void destroy() throws Exception {
System.out.println("4.1调用 DisposableBean.destroy() 方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("3.2调用 InitializingBean.afterPropertiesSet() 方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
User user = (User)applicationContext.getBean("user");
System.out.println(user);
System.out.println("调用ApplicationContextAware.setApplicationContext()");
}
}
实例化前后置代码
public class MyBeanInstant implements InstantiationAwareBeanPostProcessor {
/**
* Spring 扩展点一、在bean实例化前和实例化后
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("1.1bean的前置处理器实例前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
System.out.println(beanName + ": :" + beanClass);
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("1.3bean的前置处理器实例后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
System.out.println(beanName + ": :" + bean);
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("user".equals(beanName)) {
System.out.println("1.4调用InstantiationAwareBeanPostProcessor.postProcessProperties()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
}
}
初始化的前后置代码
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3.1 bean的后置处理器初始化前 BeanPostProcessor.postProcessBeforeInitialization");
System.out.println(beanName + ": :" + bean);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("3.4 bean的后置处理器初始化后 BeanPostProcessor.postProcessAfterInitialization");
System.out.println(beanName + ": :" + bean);
System.out.println();
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBeanPost" class="com.zly.ioc.life.MyBeanPost"/>
<bean id="myBeanInstant" class="com.zly.ioc.life.MyBeanInstant"/>
<bean id="user" class="com.zly.ioc.life.User" scope="singleton" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="dy"/>
</bean>
</beans>
总结
本文主要是介绍了Bean的生命周期,简单介绍生命周期中的各种状态概念,以及各个阶段所执行的方法和操作。
Spring 之bean的生命周期的更多相关文章
- JAVA面试题:Spring中bean的生命周期
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...
- 深入理解Spring中bean的生命周期
[Spring中bean的生命周期] bean的生命周期 1.以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期: (1).生命周期图: (2).具体事例 ...
- Spring中Bean的生命周期及其扩展点
原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6106456.html Spring中Bean的管理是其最基本的功能,根据下面的图来了解Spr ...
- 简:Spring中Bean的生命周期及代码示例
(重要:spring bean的生命周期. spring的bean周期,装配.看过spring 源码吗?(把容器启动过程说了一遍,xml解析,bean装载,bean缓存等)) 完整的生命周期概述(牢记 ...
- 面试Spring之bean的生命周期
找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下. 在说明前可以思考一下Servlet的生命周期:实例化 ...
- 通过BeanPostProcessor理解Spring中Bean的生命周期
通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...
- 一分钟掌握Spring中bean的生命周期!
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean 的别名只能维持 ...
- Spring中bean的生命周期!
Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一 ...
- 深究Spring中Bean的生命周期
前言 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到也是一头雾水,直到看到了<Spring in action>这本书,书上 ...
- Spring中 bean的生命周期
为什么要了解Spring中 bean的生命周期? 有时候我们需要自定义bean的创建过程,因此了解Spring中 bean的生命周期非常重要. 二话不说先上图: 在谈具体流程之前先看看Spring官方 ...
随机推荐
- 功能测试--APP专项
APP测试重点 APP测试与web测试的区别 APP测试常见问题 APP日志分析 APP压力稳定性测试
- 通过Rdp实现连接远程桌面
unit UnitMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...
- 2.IDEA的快捷键
1.IDEA代码等式两边自动加空格:ctrl+alt+L
- Java基础学习——Scanner
import java.util.Scanner; public class HelloWord{ public static void main(String[] args){ Scanner s= ...
- Vue 解决先渲染 暂无数据
// 组件 data(){ return { data:null // 设置默认值为null } } // template <div v-show="data != null&quo ...
- NX二次开发 版本通用方法
对于用C++做NX二次开发,随着NX的版本变更,二开所用的函数也会有相应的更新调整,生成的DLL不能跨版本运行,报错率极高,甚至不能加载.折腾了好久找到三种方法: 1.纯使用C++的代码开发或者尽可能 ...
- 解决Python写入yaml后排版混乱还丢失注释问题
转载https://www.cnblogs.com/jiahm/category/1530828.html 大家有没有遇到过在使用Python进行yaml文件写入数据后,内容排版混乱并且丢失注释问题, ...
- 痞子衡嵌入式:在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试. 我们知道恩智浦i.MXRT1xxx系列是高性能MCU ...
- 阿里云镜像创建Spring Boot工厂
参考博客:https://blog.csdn.net/qq_40052237/article/details/115794368 http://start.aliyun.com
- JS - new Function
Function 在JavaScript当中,除了可以使用function或箭头函数定义方法外,还可以使用new Function的形式动态创建函数,此时与eval()方法类似 创建一个不接收参数的方 ...