SpringBean模块(一)定义如何创建生命周期

news2025/4/26 20:05:34

一、介绍

1、简介

在 Spring 框架中,Bean 是指由 Spring 容器 管理的 Java 对象。Spring 负责创建、配置和管理这些对象,并在应用程序运行时对它们进行依赖注入(Dependency Injection,DI)。

通俗地讲,Spring Bean 就是 Spring 容器中的一个组件,它可以是一个普通的 Java 类,但被 Spring 管理起来后,就称为 "Bean"。

2、核心特点

  • 由 Spring 容器管理

    Bean 的生命周期由 Spring 负责,不需要手动创建和销毁。
  • 通过依赖注入(DI)管理对象

    Spring 自动为 Bean 注入所需的依赖,减少代码耦合。
  • 可以是任何 Java 对象

    普通 Java 类、Service、Repository、Controller 都可以是 Spring Bean。

二、如何创建 Spring Bean

有几下几种方法:

1、自动扫描(使用 @Component及其派生注解

Spring 提供了一系列注解(@Component@Service@Repository@Controller),用于标识一个类是 Spring Bean:

见注解篇

Springbean(二)@Component及其派生注解自动注入(1)介绍和规范_component 注入-CSDN博客

Springbean(二)@Component及其派生注解自动注入(2)使用注意和加载问题-CSDN博客

(1)注册

@Component 让 Spring 在 类路径扫描(Component Scanning) 时自动发现该类并注册为 Bean。

import org.springframework.stereotype.Component;

@Component // 让 Spring 扫描并管理这个类
public class MyBean {
    public void sayHello() {
        System.out.println("Hello, Spring Bean!");
    }
}
 (2)使用

使用 @Autowired 注入 Bean

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private MyBean myBean; // 依赖注入

    public void doSomething() {
        myBean.sayHello();
    }
}
2、手动注册 Bean(使用 @Bean

如果不能修改原始类(例如第三方库),可以使用 @Bean 方法在 @Configuration 类中手动注册。

(1)注册
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean(); // 手动创建 Bean
    }
}
(2)使用

  同上

3、传统方式(在 XML 配置中定义 Bean)

(1)注册

  Spring 也支持 XML 方式定义 Bean:

<bean id="myBean" class="com.example.MyBean"/>

(2)使用

然后在 Java 代码中获取 Bean:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

三、生命周期

1、概述
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements InitializingBean, DisposableBean {

    public MyBean() {
        System.out.println("1️⃣ Bean 实例化(Constructor 调用)");
    }

    // 依赖注入后执行
    @PostConstruct
    public void postConstruct() {
        System.out.println("2️⃣ @PostConstruct 方法执行");
    }

    // 实现 InitializingBean 接口
    @Override
    public void afterPropertiesSet() {
        System.out.println("3️⃣ afterPropertiesSet() 方法执行(InitializingBean)");
    }

    // Bean 可用阶段(业务方法)
    public void doSomething() {
        System.out.println("🚀 Bean 正在使用...");
    }

    // 销毁之前执行
    @PreDestroy
    public void preDestroy() {
        System.out.println("4️⃣ @PreDestroy 方法执行");
    }

    // 实现 DisposableBean 接口
    @Override
    public void destroy() {
        System.out.println("5️⃣ destroy() 方法执行(DisposableBean)");
    }
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class BeanLifecycleApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(BeanLifecycleApplication.class, args);
        
        // 获取 Bean 并调用方法
        MyBean myBean = context.getBean(MyBean.class);
        myBean.doSomething();

        // 关闭 Spring 容器(触发 Bean 销毁)
        ((SpringApplication) context).close();
    }
}

一句话总结:Spring 负责 Bean 生命周期,开发者可以在关键阶段自定义行为! 

(1)实例化(Instantiation)

 Spring 通过 new 反射创建 Bean 实例。

(2)属性填充(Populate Properties)

Spring 依赖注入,设置 Bean 的 @Autowired 或 XML 配置的属性;

(3)BeanPostProcessor#postProcessBeforeInitialization();
(4)初始化(Initialization)
  • 调用 InitializingBean#afterPropertiesSet()(如果实现了 InitializingBean

  • 调用 @PostConstruct 标注的方法(如果有)

(5)BeanPostProcessor#postProcessAfterInitialization()
(6)Bean 可用(In Use)
(7)销毁(Destruction)
  • 调用 @PreDestroy 标注的方法(如果有)

  • 调用 DisposableBean#destroy()(如果实现了 DisposableBean

  • XML 配置或 @Bean(destroyMethod="xxx") 自定义销毁方法

看下具体流程

1、创建前准备阶段

在这个阶段,Spring上下文和相关配置被解析,查找与Bean相关的配置内容,如`init-method`和`destory-method`,以及BeanFactoryPostProcessor等前置和后置处理。这些配置允许开发者在Bean加载过程中实现扩展机制。

2、实例化Bean

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。

对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。

通过反射机制,Spring创建Bean的实例对象。在这个阶段,Spring会扫描和解析Bean声明的属性。

3、依赖注入阶段

实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成属性设置与依赖注入。

4、其他处理

4.1、处理Aware接口

Spring会检测该对象是否实现了xxxAware接口,通过Aware类型的接口,可以让我们拿到Spring容器的一些资源:

①如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,传入Bean的名字;
②如果这个Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
②如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;

4.2、BeanPostProcessor前置处理:

如果想对Bean进行一些自定义的前置处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。

4.3、InitializingBean:

如果Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。

4.4、init-method:

如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

4.5、BeanPostProcessor后置处理:

如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;

以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

5、DisposableBean:

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法; 

6、destroy-method:

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

以上生命周期包含两个重要的事件:初始化和销毁事件。初始化事件发生在Bean的属性赋值之后,在`init-method`操作之前,而销毁事件则发生在Bean在容器关闭时,内存释放之前。

2、生命周期回调方式

Spring 提供多种方式来定制 Bean 生命周期的行为:

(1)使用 @PostConstruct@PreDestroy(推荐)

推荐使用 @PostConstruct@PreDestroy,因为它们是标准 Java 注解,和 Spring 解耦。

  • @PostConstruct:Bean 初始化完成后执行

  • @PreDestroy:Bean 销毁前执行

@Component
public class MyBean {
    @PostConstruct
    public void init() {
        System.out.println("Bean 初始化完成");
    }

    @PreDestroy
    public void cleanup() {
        System.out.println("Bean 即将被销毁");
    }
}
(2)实现 InitializingBeanDisposableBean

Spring 提供了 InitializingBeanDisposableBean 两个接口,不推荐使用,因为这样会耦合 Spring 框架,影响代码的可移植性。

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;

@Component
public class MyBean implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() {
        System.out.println("Bean 初始化 afterPropertiesSet()");
    }

    @Override
    public void destroy() {
        System.out.println("Bean 销毁 destroy()");
    }
}
(3)使用 @Bean(initMethod, destroyMethod)

如果是通过 @Configuration 手动注册 Bean,可以使用 @BeaninitMethoddestroyMethod

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

@Configuration
public class MyConfig {
    @Bean(initMethod = "init", destroyMethod = "cleanup")
    public MyBean myBean() {
        return new MyBean();
    }
}

class MyBean {
    public void init() {
        System.out.println("Bean 初始化(initMethod)");
    }

    public void cleanup() {
        System.out.println("Bean 销毁(destroyMethod)");
    }
}
(4)使用 BeanPostProcessor(高级用法)

如果需要在 Bean 初始化前后进行操作,可以使用 BeanPostProcessor,适用于 AOP、代理、动态增强等高级需求。

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("🚀 BeanPostProcessor - 初始化前:" + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("✅ BeanPostProcessor - 初始化后:" + beanName);
        return bean;
    }
}
3、什么时候会触发 Bean 的销毁
  • 单例(Singleton)Bean:Spring 容器关闭时销毁

  • 多例(Prototype)Bean:Spring 不会 自动管理销毁,需要手动处理

  • Web 应用

    • request 作用域:HTTP 请求结束时销毁

    • session 作用域:Session 结束时销毁

    • application 作用域:Web 应用关闭时销毁

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

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

相关文章

Redis-04.Redis常用命令-字符串常用命令

一.字符串操作命令 set name jack 点击左侧name&#xff0c;显示出值。 get name get abc&#xff1a;null setex key seconds value&#xff1a;设置过期时间&#xff0c;过期后该键值对将会被删除。 然后再get&#xff0c;在过期时间内可以get到&#xff0c;过期get不到。…

Epub转PDF软件Calibre电子书管理软件

Epub转PDF软件&#xff1a;Calibre电子书管理软件 https://download.csdn.net/download/hu5566798/90549599 一款好用的电子书管理软件&#xff0c;可快速导入电脑里的电子书并进行管理&#xff0c;支持多种格式&#xff0c;阅读起来非常方便。同时也有电子书格式转换功能。 …

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读

FAST-LIVO2 Fast, Direct LiDAR-Inertial-Visual Odometry论文阅读 论文下载论文翻译FAST-LIVO2: 快速、直接的LiDAR-惯性-视觉里程计摘要I 引言II 相关工作_直接方法__LiDAR-视觉&#xff08;-惯性&#xff09;SLAM_ III 系统概述IV 具有顺序状态更新的误差状态迭代卡尔曼滤波…

【Git】--- Git远程操作 标签管理

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Git 前面我们学习的操作都是在本地仓库进行了&#xff0c;如果团队内多人协作都在本地仓库操作是不行的&#xff0c;此时需要新的解决方案 --- 远程仓库。…

论文阅读笔记——ST-4DGS,WideRange4D

ST-4DGS ST-4DGS 论文 在 4DGS 中&#xff0c;变形场 F \mathcal{F} F 与运动参数 X 和形状参数 ( S , R ) (S,R) (S,R) 高度耦合&#xff0c;导致训练时高斯表示紧凑型退化&#xff0c;影响动态渲染质量。由此&#xff0c;本文提出两种方法解耦运动与形状参数&#xff0c;保…

[python]基于yolov8实现热力图可视化支持图像视频和摄像头检测

YOLOv8 Grad-CAM 可视化工具 本工具基于YOLOv8模型&#xff0c;结合Grad-CAM技术实现目标检测的可视化分析&#xff0c;支持图像、视频和实时摄像头处理。 功能特性 支持多种Grad-CAM方法实时摄像头处理视频文件处理图像文件处理调用简单 环境要求 Python 3.8需要电脑带有…

豪越科技消防一体化平台:打通消防管理“任督二脉”

在城市的车水马龙间&#xff0c;火灾隐患如潜藏的暗礁&#xff0c;威胁着人们的生命财产安全。传统消防管理模式在现代社会的复杂环境下&#xff0c;逐渐显露出诸多弊端。内部管理分散混乱&#xff0c;人员、装备、物资管理缺乏统一标准和高效流程&#xff1b;外部监管困难重重…

【Matlab】-- 基于MATLAB的美赛常用多种算法

文章目录 文章目录 01 内容概要02 各种算法基本原理03 部分代码04 代码下载 01 内容概要 本资料集合了多种数学建模和优化算法的常用代码资源&#xff0c;旨在为参与美国大学生数学建模竞赛&#xff08;MCM/ICM&#xff0c;简称美赛&#xff09;的参赛者提供实用的编程工具和…

机器学习课程

前言 课程代码和数据文件&#xff1a; 一、机器学习概述 1.1.人工智能概述 机器学习和人工智能&#xff0c;深度学习的关系 机器学习是人工智能的一个实现途径深度学习是机器学习的一个方法发展而来 达特茅斯会议-人工智能的起点 1956年8月&#xff0c;在美国汉诺斯小镇宁静…

AIGC(生成式AI)试用 28 -- 跟着清华教程学习 - AIGC发展研究 3.0

目标&#xff1a;继续学习 - 信息不对称、不平等、隐私泄露和数据滥用 - 问、改、创、优 - “概率预测&#xff08;快速反应&#xff09;”模型和“链式推理&#xff08;慢速思考&#xff09;”模型 - 思维滞环现象解决思路&#xff1a;1.调整提问&#xff1a;改变问题方式&…

问题:md文档转换word,html,图片,excel,csv

文章目录 问题&#xff1a;md文档转换word&#xff0c;html&#xff0c;图片&#xff0c;excel&#xff0c;csv&#xff0c;ppt**主要职责****技能要求****发展方向****学习建议****薪资水平** 方案一&#xff1a;AI Markdown内容转换工具打开网站md文档转换wordmd文档转换pdfm…

【Java】面向对象之static

用static关键字修饰成员变量 有static修饰成员变量&#xff0c;说明这个成员变量是属于类的&#xff0c;这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个&#xff0c;所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量…

Anaconda安装-Ubuntu-Linux

1、进入Anaconda官网&#xff0c;以下载最新版本&#xff0c;根据自己的操作系统选择适配的版本。 2、跳过注册&#xff1a; 3、选择适配的版本&#xff1a; 4、cd ~/anaconda_download 5、bash Anaconda3-2024.10-1-Linux-x86_64.sh 6、按Enter或PgDn键滚动查看协议&…

Linux 配置NFS服务器

1. 开放/nfs/shared目录&#xff0c;供所有用户查阅资料 服务端 &#xff08;1&#xff09;安装nfs服务&#xff0c;nfs-utils包中包含rpcbind&#xff08;rpc守护进程&#xff09; [rootnode1-server ~]# yum install -y nfs-utils # nfs-utils包中包含rpcbind [rootnode…

塔能科技:用精准节能撬动社会效益的行业杠杆

在全球积极践行可持续发展理念的当下&#xff0c;能源高效利用与节能减排&#xff0c;已然成为各行各业实现高质量发展绕不开的关键命题。对企业来说&#xff0c;节能早已不是一道可做可不做的选择题&#xff0c;而是关乎生存与发展、社会责任与竞争力的必答题。塔能科技推出的…

Java 大视界 -- Java 大数据在自动驾驶高精度地图数据更新与优化中的技术应用(157)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

nginx https配置

一.https配置 HTTPS 协议是由HTTP 加上TLS/SSL 协议构建的可进行加密传输、身份认证的网络协议&#xff0c;主要通过数字证书、加密算法、非对称密钥等技术完成互联网数据传输加密&#xff0c;实现互联网传输安全保护。 1.生成证书 openssl genrsa -des3 -out server.key 20…

每日一题洛谷P10901 [蓝桥杯 2024 省 C] 封闭图形个数c++

排序思想&#xff0c;只不过这时的排序与之前的略有不同&#xff0c;com函数中要先比较封闭图形再比较真实的大小&#xff0c;多了一步&#xff0c;但是原理还是一样的 #include<iostream> #include<algorithm> #include<vector> using namespace std; //统…

天锐蓝盾终端安全防护——企业终端设备安全管控

从办公室的台式电脑到员工手中的移动终端&#xff0c;这些设备不仅是工作的得力助手&#xff0c;更是企业数据的重要载体。然而&#xff0c;随着终端设备的广泛使用&#xff0c;安全风险也如影随形。硬件设备使用不当、数据随意传输等问题频发&#xff0c;使得企业数据面临着泄…

3.27学习总结 爬虫+二维数组+Object类常用方法

高精度&#xff1a; 一个很大的整数&#xff0c;以字符串的形式进行接收&#xff0c;并将每一位数存储在数组内&#xff0c;例如100&#xff0c;即存储为[1][0][0]。 p2437蜜蜂路线 每一个的路线数前两个数的路线数相加。 #include <stdio.h> int a[1005][1005]; int …