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官方 ...
随机推荐
- day47-Mysql初识
1.数据库的演变过程-- 文件存储(不同用户之间数据格式不一致,杂乱)==> 软件开发目录规范(限定了储存的具体位置,不能网络通信)==>数据库 数据库就是一款基于网络通信操作文件的应用程 ...
- 安装DevExpress VCL,使用时报错 某单元文件找不到的解决办法
1.新建一个工程做为测试 2.点击projecct-->options 3. 4. 5.在上4图上的红框内加入packages文件 dxCoreRS27;dxGDIPlusRS27;dxComn ...
- 实验4_开源控制器实践——OpenDaylight
基础要求 需要提交两张图, 一是Mininet拓扑生成并连接控制器的结果 二是Mininet中ping测试截图,并体现个人信息 进阶要求 1.获取拓扑的交换机 2.获取流表状态数量 3.获取指定交换机 ...
- 问道Golang,6月龄必知必会(二)
在我看来,golnag有许多反直观的设计,而且这些设计通常不能自圆其说,导致gohper一而再再而三的调入陷阱. 网上也有很多gohper总结了一些笔记,我再提炼精简一下,挂在脑图树上便于记忆. 值类 ...
- SpringBoot笔记--Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.报错的解决
问题描述 写了SpringBoot代码之后,运行不出来结果,报出这样的一个错误:Failed to configure a DataSource: 'url' attribute is not spe ...
- Javaweb学习笔记第十四弹---对于Cookie和Filter的学习
Apache Tomcat - Tomcat Native Downloads 会话追踪技术 会话:打开浏览器,建立连接,直到一方断开连接,会话才会结束:在一次会议中,可以有多次请求. 会话追踪:在多 ...
- 使用sync.Once实现高效的单例模式
1. 简介 本文介绍使用sync.Once来实现单例模式,包括单例模式的定义,以及使用sync.Once实现单例模式的示例,同时也比较了其他单例模式的实现.最后以一个开源框架中使用sync.Once实 ...
- Simulink的MATLAB function使用
note 2021-02-21 下面的文章来自我的公众号 yhm同学 note 2021-04-01 今天审稿,发现存在着一些我没有发现的错误,但是我不想修改了. 原文链接 https://mp.we ...
- TypeScript 学习笔记 — 类型兼容 (十)
目录 一.基本数据类型的兼容性 二.接口兼容性 三.函数的兼容性 四.类的兼容性 类的私有成员和受保护成员 五.泛型的兼容性 六.枚举的兼容性 标称类型简短介绍 TS 是结构类型系统(structur ...
- Redis 线程模型
一.概述 [1]Redis 是基于 Reactor 模式开发的网络事件处理器:这个处理器被称为文件事件处理器(file event handler),这个文件事件处理器是单线程的,所以 Redis 才 ...