谈谈Spring中Bean的生命周期?(让你瞬间通透~)

news/2024/11/23 23:59:01/

目录

1.Bean的生命周期

1.1、概括

1.2、图解

2、代码示例

2.1、初始化代码

2.2、初始化的前置方法和后置方法(重写)

2.3、Spring启动类

2.4、执行结果

2.5、经典面试问题

3.总结


1.Bean的生命周期


1.1、概括

Spring中Bean的生命周期就是Bean在Spring中从创建到销毁的整个过程,主要分为以下5个部分:

1.实例化:给Bean分配内存空间(对应JVM中的“加载”,这里只是分配了内存);

2.设置属性:进行Bean的注入和装配;

3.初始化:

        a) 执行各种通知;

        b) 执行初始化的前置工作;

        c) 进行初始化工作(使用注解 @PostConstruct 初始化 或者 使用(xml)init-method 初始化, 前者技术比后者技术先进~);

        d) 执行初始化的后置工作;

4.使用Bean;

5.销毁Bean。

值得注意的是:实例化和初始化是两个完全不同的过程,前者只是给Bean分配内存空间,而后者则是将程序执行权从系统级别转到用户级别,执行用户添加的业务代码。

1.2、图解

下图以买房、盖房、入住、卖房为栗子,方便理解~

2、代码示例


2.1、初始化代码

以下,我将在Spring中,演示Bean的生命周期:

创建一个类,名为BeanLifeComponent(这个名字是自定义的), 写下初始化的各类操作:

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;@Component
public class BeanLifeComponent implements BeanNameAware {//执行各种通知@Overridepublic void setBeanName(String s) {System.out.println("执行了通知");}//初始化的前置和后置方法不能写在这个Bean中!//执行初始化方法(注解)@PostConstructpublic void postConstruct() {System.out.println("通过注解 @PostConstruct 执行了初始化方法");}//使用public void useBean() {System.out.println("使用Bean");}//销毁@PreDestroypublic void preDestory() {System.out.println("执行了销毁方法");}}

注意:1.这里不能写出实例化过程,因为给Bean分配内存对应JVM类加载过程;2.当前这个Bean中不能写初始化的前置方法和后置方法,否则不会执行,因为初始化的前置方法和后置方法是需要继承BeanPostProcessor接口,重写两个方法实现的, 并且是为所有 Bean 服务的,而非为某一个 Bean 服务的,若写在一个某一个Bean中,则不会执行。

2.2、初始化的前置方法和后置方法(重写)

另外再创建一个类(避免在一个Bean中),自定义名为 MyBeanPostProcessor ,接着继承BeanPostProcessor接口,重写初始化的前置方法和后置方法,如下代码:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;@Component
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("执行了初始化的前置方法");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("执行了初始化的后置方法");return bean;}
}

2.3、Spring启动类

最后在Spring启动类中获取Bean对象,如下代码:

import com.demo3.component.BeanLifeComponent;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App3 {public static void main(String[] args) {ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");//获取BeanBeanLifeComponent beanLifeComponent =context.getBean("beanLifeComponent", BeanLifeComponent.class);//使用BeanbeanLifeComponent.useBean();//销毁Beancontext.destroy();}
}

为什么这里不使用 ApplicationContext 而是使用它的子类 ClassPathXmlApplicationContext 呢?因为 ClassPathXmlApplicationContext 中有destroy销毁方法(用来销毁容器,容器销毁了,Bean自然就没了),而ApplicationContext 中没有这个销毁方法,演示的时候,就体现不出来了。

2.4、执行结果

从执行结果来看,符合咱们预期~

2.5、经典面试问题

        那么是否可以先执行 初始化 再执行 设置属性 呢? 不可以!想象一下,如果在初始化的方法中要用你设置的属性,就会引发空指针异常,如下代码:

@Controller
public class StudentController {//属性注入@Autowiredprivate Student student;//初始化@PostConstructpublic void init() {student.setName("周杰伦");}}

如果你先执行了初始化 init() 方法,而 init() 方法中需要使用属性注入后得到的Student对象,那么此时还没有注入就进行修改,就会引发空指针异常。
 

3.总结


Spring中Bean的生命周期就是Bean在Spring中从创建到销毁的整个过程。

主要就是由:1.实例化、2.设置属性:进行Bean的注入和装配、3.初始化、4.使用Bean、5.销毁Bean,这五步构成,并且任何顺序都不可以随意调换。

Bean的执行流程属于常见面试题,一定要在理解的基础上牢记!



http://www.ppmy.cn/news/23634.html

相关文章

Negative Prompt in Stable Diffusion

必读链接:https://www.reddit.com/r/StableDiffusion/comments/z7salo/with_the_right_prompt_stable_diffusion_20_can_do/ A lot of people have noticed that Negative Prompt works wonders in 2.0, and works even better in 2.1. Negative hints are the op…

怡合达业务大规模容器化最佳实践

作者:肖念康,东莞怡合达智能制造供应链资深 Java 开发工程师,主要负责公司内部 DevOps、代码托管平台、任务需求管理平台的研发及其他项目的管理,云原生的研究与开发工作。 公司简介 怡合达致力于自动化零部件研发、生产和销售&am…

【笔记】移动端自动化:adb调试工具+appium+UIAutomatorViewer

学习源: https://www.bilibili.com/video/BV11p4y197HQ https://blog.csdn.net/weixin_47498728/category_11818905.html 一、移动端测试环境搭建 学习目标 1.能够搭建java 环境 2.能够搭建android 环境 (一)整体思路 我们的目标是Andr…

雪花算法snowflake

snowflake中文的意思是 雪花,雪片,所以翻译成雪花算法。它最早是twitter内部使用的分布式环境下的唯一ID生成算法。在2014年开源。雪花算法产生的背景当然是twitter高并发环境下对唯一ID生成的需求,得益于twitter内部高超的技术,雪…

【逐步剖C】-第六章-结构体初阶

一、结构体的声明 1. 结构体的基本概念 结构体是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。结构体使得C语言有能力描述复杂类型。 如学生,有姓名、学号、性别等;如书,有作者,出版日期…

冷知识|鹤顶红还能用来修长城?

大家好,我是建模助手。 在上篇浅浅地蹭了波热点之后,我灵机一动,倒不如也搞一搞建筑方面的冷知识?冷热搭配,事半功倍... 问问大家,如果谈起古建筑,关键词都有什么?是庄严、震撼、壮…

计算机入门基础知识大全

♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的,绽…

MySQL8.0之前实现row_number以及计算玩家连续登录天数

使用MySQL 5.7版本统计 玩家连续登录天数 原始数据 玩家同一天多次登录只保留一条 select DISTINCT(FROM_UNIXTIME(login_time,%Y-%m-%d)) as login_date,rid from t_log_login order by rid; 借助两个变量统计每个玩家登录日期对应的次数 SELECT * FROM(SELECT DISTINCT …