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官方 ...
随机推荐
- idea修改背景颜色|护眼色|项目栏背景修改
https://blog.csdn.net/heytyrell/article/details/89743068
- SQLyog中创建的数据库在idea找不到
在里面把需要的数据库
- 泛型 ? extends E ? super E的区别
package cn.itcast.generic; import java.util.ArrayList;import java.util.Collection; public class Supp ...
- python pandas dataframe excel xlwings docx 常用简单函数方法汇总
# -*- coding: UTF-8 -*-import pandas as pdimport numpy as npimport datetimeimport osimport sysimport ...
- arcengine动态显示所需字段值
需求:实现和GIS桌面端中Identify的类似功能,鼠标滑动的时候可以显示鼠标所在位置的要素的指定字段的值.. 主要操作流程: ①先打开一个对话框,用于选择需要显示的图层和字段名 ②点击确定之后,在 ...
- mysql error Code 1441:datetime function: datetime field overflow
mysql error Code 1441:datetime function: datetime field overflow 网上找了好久,也没有解决 最后发现有个left join 表,on关 ...
- SpringBoot笔记--配置->profile的配置
profile--动态配置切换 profile配置方式: 使用spring.profile.active=进行激活.properties文件 直接使用一个.yml文件代替多文件配置 使用---分隔符分 ...
- 验证码案例的实现---MyBatis+Session+Cookie
展示验证码(jsp页面) 首先,我们需要自己利用BufferedImage类去生成一张可以变换的验证码图片: 之后,我们就可以利用这样一串代码去将验证码里面的内容获取到: 这是一串测试代码: Outp ...
- Pod概述
Pod的类型 Pod的类型有如下两个: 自主式Pod:自主式Pod的含义简白来说就是不是被控制器管理的Pod,另一种就是被控制管理的Pod,不被控制器管理的Pod你会发现,它一旦死亡的话,就没有人把它 ...
- 使用EFCore的Code First和MySql数据库迁移
1. 感慨一下 随着.net core的持续更新和升级,至少对于从事.net开发的人员和即将踏入这个领域的人来说,我相信大家的热情还是持续高涨的.国内的.net开发生态相比于之前来说,还是大有所好转的 ...