Spring中Bean的生命周期管理

news2024/11/13 8:05:12

Spring框架中的Bean生命周期是指从创建到销毁的整个过程。在这个过程中,Spring容器会负责管理Bean的状态和行为。以下是Spring中Bean生命周期的详细解释:

  1. 实例化:Spring容器根据Bean的定义信息,通过反射机制创建Bean对象。

  2. 设置属性值:Spring容器会根据Bean定义中的配置信息,为Bean对象设置属性值。这包括依赖注入的过程。

  3. 调用BeanNameAware接口方法:如果Bean实现了BeanNameAware接口,Spring容器会调用setBeanName()方法,将Bean的名称传递给Bean。

  4. 调用BeanFactoryAware接口方法:如果Bean实现了BeanFactoryAware接口,Spring容器会调用setBeanFactory()方法,将BeanFactory实例传递给Bean。

  5. 调用ApplicationContextAware接口方法:如果Bean实现了ApplicationContextAware接口,Spring容器会调用setApplicationContext()方法,将ApplicationContext实例传递给Bean。

  6. 调用BeanPostProcessor的postProcessBeforeInitialization()方法:Spring容器会调用实现了BeanPostProcessor接口的类的postProcessBeforeInitialization()方法,对Bean进行预初始化处理。

  7. 调用InitializingBean接口方法:如果Bean实现了InitializingBean接口,Spring容器会调用afterPropertiesSet()方法,用于Bean的初始化操作。

  8. 调用自定义的初始化方法:如果在Bean定义中配置了init-method属性,Spring容器会调用指定的初始化方法。

  9. 调用BeanPostProcessor的postProcessAfterInitialization()方法:Spring容器会调用实现了BeanPostProcessor接口的类的postProcessAfterInitialization()方法,对Bean进行初始化后的处理。

  10. Bean可以被使用:此时Bean已经初始化完成,可以被应用程序正常使用。

  11. 调用DisposableBean接口方法:当容器关闭时,如果Bean实现了DisposableBean接口,Spring容器会调用destroy()方法,用于Bean的资源释放操作。

  12. 调用自定义的销毁方法:如果在Bean定义中配置了destroy-method属性,Spring容器会调用指定的销毁方法。

  13. 销毁Bean:Spring容器销毁Bean对象,释放内存资源。

总结一下,Spring中Bean的生命周期包括实例化、设置属性值、调用Aware接口方法、调用BeanPostProcessor的前后处理方法、调用InitializingBean和DisposableBean接口方法以及自定义的初始化和销毁方法。在这个过程中,Spring容器负责管理Bean的状态和行为。

以下为示例代码

MyBean

package org.example.bean01.ch01;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {

    private String name;
    private String address;
    private int phone;
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext context;

    // 通过<bean>的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("调用<bean>的init-method属性指定的初始化方法");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        System.out.println("调用ApplicationContextAware.setApplicationContext接口");
    }

    public String show() {
        return this.toString();
    }

    public MyBean() {
        System.out.println("调用MyBean的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("注入属性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("注入属性address");
        this.address = address;
    }

    public int getPhone() {
        return phone;
    }

    public void setPhone(int phone) {
        System.out.println("注入属性phone");
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "MyBean [address=" + address + ", name=" + name + ", phone=" + phone + "]";
    }

    // 这是BeanFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }

    // 这是BeanNameAware接口方法
    @Override
    public void setBeanName(String arg0) {
        System.out.println("调用BeanNameAware.setBeanName()");
        this.beanName = arg0;
    }

    // 这是InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("调用InitializingBean.afterPropertiesSet()");
    }

    // 这是DiposibleBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("调用DiposibleBean.destory()");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("调用<bean>的destroy-method属性指定的初始化方法");
    }
}

MyBeanFactoryPostProcessor

package org.example.bean01.ch01;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements ApplicationContextAware, BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {

    private String name;
    private String address;
    private int phone;
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext context;

    // 通过<bean>的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("调用<bean>的init-method属性指定的初始化方法");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        System.out.println("调用ApplicationContextAware.setApplicationContext接口");
    }

    public String show() {
        return this.toString();
    }

    public MyBean() {
        System.out.println("调用MyBean的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("注入属性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("注入属性address");
        this.address = address;
    }

    public int getPhone() {
        return phone;
    }

    public void setPhone(int phone) {
        System.out.println("注入属性phone");
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "MyBean [address=" + address + ", name=" + name + ", phone=" + phone + "]";
    }

    // 这是BeanFactoryAware接口方法
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }

    // 这是BeanNameAware接口方法
    @Override
    public void setBeanName(String arg0) {
        System.out.println("调用BeanNameAware.setBeanName()");
        this.beanName = arg0;
    }

    // 这是InitializingBean接口方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("调用InitializingBean.afterPropertiesSet()");
    }

    // 这是DiposibleBean接口方法
    @Override
    public void destroy() throws Exception {
        System.out.println("调用DiposibleBean.destory()");
    }

    // 通过<bean>的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("调用<bean>的destroy-method属性指定的初始化方法");
    }
}

MyBeanPostProcessor

package org.example.bean01.ch01;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {

    public MyBeanPostProcessor() {
        super();
        System.out.println("调用BeanPostProcessor实现类构造器");
    }

    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
        System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
        return arg0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
        System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
        return arg0;
    }
}

AppConfig

package org.example.bean01.ch01;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "org.example.bean01.ch01")
public class AppConfig {

    @Bean
    public MyBeanPostProcessor myBeanPostProcessor() {
        return new MyBeanPostProcessor();
    }

    @Bean
    public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor() {
        return new MyBeanFactoryPostProcessor();
    }

    @Bean(initMethod = "myInit", destroyMethod = "myDestory")
    public MyBean myBean() {
        return new MyBean();
    }

}

启动类BeanDemo

package org.example.bean01.ch01;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class BeanDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyBean myBean = context.getBean(MyBean.class);

        // 使用Bean
        System.out.println("Using bean: " + myBean.show());

        context.close();
    }
}

执行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2083255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

bat文件入门

1简介 BAT&#xff08;批处理&#xff09;脚本是一种在 Windows 系统中执行的脚本语言&#xff0c;用于自动化不同类型的任务。它可以执行多个命令和操作&#xff0c;并具有变量、参数、流程控制和文件处理等功能。BAT 脚本可以通过命令行或双击执行&#xff0c;并可以在脚本中…

vscode中如何设置不显示隐藏文件

在vscode中&#xff0c;有时候&#xff0c;会显示一些隐藏文件&#xff0c;如何设置让其不显示呢&#xff1f; 解决办法 例如&#xff1a;我这里有一个.vscode隐藏文件夹&#xff0c;是vscode默认生成的一个配置目录&#xff0c;我想要它不在资源管理器中进行显示。 操作步骤&a…

51单片机-LED闪烁

时间&#xff1a;2024.8.28 作者&#xff1a;Whappy 目的&#xff1a;学习51单片机 代码&#xff1a; #include <REGX52.H> #include "intrins.h"void Delay500ms() //11.0592MHz {unsigned char i, j, k;_nop_();i 4;j 129;k 119;do{do{while (--k);} …

vue实现二维码批量生成和打印

摘要&#xff1a;实现一个可以根据数据批量生成二维码标签页个批量打印标签页的组件。难点在于&#xff0c;文字和二维码如何合成一张图片进行打印&#xff0c;因为生成的二维码是图片&#xff0c;但文字和二维码整个内容其实是一个div。 效果展示 标签批量生成效果&#xff…

Google Earth Engine(GEE)——光谱指数影像的加载(真彩色和假彩色)以及NDVI的计算

简介 本实验的目的是了解一系列光谱指数,并培养计算您需要的任何指数的技能。在开始之前,我们将在上周实验室的基础上学习如何为任何感兴趣的地理位置查找图像。 编码面板的正上方是搜索栏。在此 GEE 搜索栏中搜索“达尔文”,然后单击结果以将地图平移和缩放至达尔文(图 …

Ubuntu中PCL、Eigen、ROS、Ceres、VScode相关操作,安装,卸载,文件存储位置基础合集

Ubuntu中PCL相关操作 查看PCL对应的版本号 apt-cache show libpcl-dev卸载PCL相关命令 sudo apt-get remove libpcl-dev如果想要完全卸载相关软件包及其配置文件&#xff0c;需要加上--purge参数&#xff1a; sudo apt-get --purge remove libpcl-dev Ubuntu中eigen相关操…

Qwen-VL模型微调及遇到的一些小问题

Qwen-VL 是阿里云研发的大规模视觉语言模型&#xff08;Large Vision Language Model, LVLM&#xff09;。Qwen-VL 可以以图像、文本、检测框作为输入&#xff0c;并以文本和检测框作为输出。相比较前文提到的llava-llama3的模型&#xff0c;它相对更成熟一些&#xff0c;功能更…

设计模式篇(DesignPattern - 行为型模式)(持续更新迭代)(图片待加载)

目录 一、模版方法模式&#xff08;制作豆浆问题&#xff09; 1. 豆浆制作问题 2. 模板方法模式 2.1. 基本介绍 2.2. 代码实现 2.3. 钩子方法 2.4. 应用案例 应用一&#xff1a;Android中View的draw 应用二&#xff1a;Spring 框架应用的源码分析 2.5. 注意事项和细节…

手持机定制方案_安卓手机主板定制_MTK联发科智能终端方案开发

手持机定制方案搭载了8核CPU&#xff0c;主频高达2.0GHz&#xff0c;并运行Android12.0操作系统。无论是多媒体播放、游戏娱乐还是多任务处理&#xff0c;均能带来极为流畅的体验。高达8GB的RAM确保应用程序和游戏可以顺畅运行&#xff0c;而256GB的内部存储空间以及支持扩展至…

Python酷库之旅-第三方库Pandas(106)

目录 一、用法精讲 461、pandas.DataFrame.lt方法 461-1、语法 461-2、参数 461-3、功能 461-4、返回值 461-5、说明 461-6、用法 461-6-1、数据准备 461-6-2、代码示例 461-6-3、结果输出 462、pandas.DataFrame.gt方法 462-1、语法 462-2、参数 462-3、功能 …

【系统架构设计师-2017年】综合知识-答案及详解

文章目录 【第1~2题】【第3题】【第4题】【第5题】【第6题】【第7~8题】【第9~10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16~17题】【第18~19题】【第20~21题】【第22题】【第23题】【第24题】【第25题】【第26~27题】【第28题】【第29题】【第30题】【第3…

【html+css 绚丽Loading】000022 三元循环轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

【Git 学习笔记_22】Git 实用冷门操作技巧(上)

文章目录 第十一章 Git 操作技巧与诀窍简介11.1 活用 git stash11.2 保存并应用 stash 第十一章 Git 操作技巧与诀窍 本章相关主题&#xff1a; 活用 git stash&#xff08;上&#xff09; ✔️保存并应用 stash&#xff08;上&#xff09; ✔️用 git bisect 进行调试使用 g…

并发性服务器

同一时刻能处理多个客户端 多进程&#xff1a; int init_tcp_ser(const char *ip,unsigned short port) {int sockfd socket(AF_INET,SOCK_STREAM,0);if(-1 sockfd){perror("fail socket");return -1;}struct sockaddr_in ser;ser.sin_family AF_INET;ser.sin_por…

【Python 千题 —— 基础篇】简易购物车

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 设计一个在线购物车系统,该系统能够管理用户的购物行为。用户可以将商品添加到购物车中、移除购物车中的商品、查看购物车中的商品列表,并计算…

nerfstudio半离线配置踩坑记录

安装torch2.1.2 with cuda11.8 由于清华镜像源&#xff08;包括阿里源和豆瓣源&#xff09;都没有torch2.1.2cu118的包&#xff0c;因此只能从pytorch官网下载。 服务器上直接通过下面pip的方式安装会由于网络原因中断&#xff0c;无奈只能在本地先把torch的包下载下来再上传到…

8.Linux_Makefile

Makefile 1、基本知识 语法&#xff1a; 目标:依赖 //依赖可以是0个或多个&#xff0c;依赖之间用空格分隔命令 //命令前面必须有tab键 目标&#xff1a;最终要生成的文件依赖&#xff1a;生成目标所需要的文件命令&#xff1a;怎么样通过依赖来生成目标的 make访问mak…

pve首页查看功耗拓展脚本

作者&#xff1a;TP唉 https://www.bilibili.com/read/cv26924314/?jump_opus1 出处&#xff1a;bilibili 如图所示想要这全方位信息很难吗&#xff1f;不&#xff0c;很简单只需要在shell里粘贴两串代码轻松搞定&#xff01; 命令1&#xff1a;(curl -Lf -o /tmp/temp.sh ht…

CleanClip: macOS 上最干净的剪贴板管理工具

在日常工作中,我们经常需要复制粘贴各种内容。但是 macOS 自带的剪贴板功能非常有限,只能保存最后一次复制的内容。这就是为什么我们需要一个强大的剪贴板管理工具 - CleanClip。 CleanClip 是什么? CleanClip 是一款专为 Mac 用户设计的剪贴板管理工具&#xff0c;它可能是 …

day13JS-MoseEvent事件

1. MouseEvent的类别 mousedown &#xff1a;按下键mouseup &#xff1a;释放键click &#xff1a;左键单击dblclick &#xff1a;左键双击contextmenu &#xff1a;右键菜单mousemove &#xff1a;鼠标移动mouseover : 鼠标经过 。 可以做事件委托&#xff0c;子元素可以冒泡…