首页 > 其他分享 >Spring Bean 生命周期详解

Spring Bean 生命周期详解

时间:2024-06-22 09:04:13浏览次数:21  
标签:Spring void System Bean 详解 println public

Spring Bean 生命周期详解

在 Spring 框架中,Bean 的生命周期由 Spring 容器全权管理。了解和掌握 Bean 的生命周期对于使用 Spring 开发稳定且高效的应用程序至关重要。本文将详细介绍 Spring Bean 生命周期的五个主要阶段:实例化、属性注入、初始化、使用和销毁,并涵盖各个阶段的关键步骤和扩展点。

1. 实例化(Instantiation)

实例化阶段包括以下关键步骤:

  • BeanNameAware 接口:如果 Bean 实现了 BeanNameAware 接口,Spring 将调用其 setBeanName 方法,将 Bean 的名称传递给它。
  • BeanFactoryAware 接口:如果 Bean 实现了 BeanFactoryAware 接口,Spring 将调用其 setBeanFactory 方法,将 BeanFactory 实例传递给它。

这些步骤确保 Bean 具有必要的上下文信息,可以与 Spring 容器进行交互。

@Override
public void setBeanName(String beanName) {
    System.out.println("BeanNameAware: setBeanName called with name " + beanName);
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("BeanFactoryAware: setBeanFactory called");
}

2. 属性注入(Property Injection)

在实例化之后,Spring 容器会根据配置文件或注解,将配置的属性值或依赖对象注入到 Bean 实例中。这一阶段包括以下关键步骤:

  • 属性设置:Spring 容器根据配置文件或注解,将配置的属性值注入到 Bean 实例中。
  • 依赖注入:Spring 容器根据配置文件或注解,将依赖对象注入到 Bean 实例中。
public class MyBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

3. 初始化(Initialization)

初始化阶段是 Bean 生命周期中最复杂的阶段,它包括属性设置、依赖注入和初始化方法的调用。该阶段包括以下关键步骤:

  • BeanPostProcessor 的 postProcessBeforeInitialization 方法:Spring 调用所有注册的 BeanPostProcessor 实现的 postProcessBeforeInitialization 方法,以便在 Bean 初始化前对其进行处理。
  • InitializingBean 接口和自定义初始化方法:如果 Bean 实现了 InitializingBean 接口,Spring 将调用其 afterPropertiesSet 方法。此外,如果配置了自定义的初始化方法,Spring 也会调用该方法。
  • @PostConstruct 注解:如果 Bean 的某个方法使用了 @PostConstruct 注解,Spring 容器将在依赖注入完成后调用该方法。@PostConstruct 注解用于标注在依赖注入完成后需要执行的初始化方法,比实现 InitializingBean 接口更加灵活和通用。
  • BeanPostProcessor 的 postProcessAfterInitialization 方法:Spring 调用所有注册的 BeanPostProcessor 实现的 postProcessAfterInitialization 方法,以便在 Bean 初始化后对其进行处理。
import javax.annotation.PostConstruct;

public class MyBean {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct: init method called");
        this.name = "Initialized Bean";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean: afterPropertiesSet called");
    }

    public void customInit() {
        System.out.println("Custom init-method: customInit called");
    }
}

4. 使用(Ready to Use)

在完成初始化后,Bean 进入使用阶段。在这个阶段,Bean 处于完全初始化状态,可以被应用程序使用。这个阶段没有特定的扩展点,但这是应用程序逻辑使用和操作 Bean 的主要时间段。

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    MyBean myBean = context.getBean(MyBean.class);
    System.out.println("Using MyBean: " + myBean);
    context.close();
}

5. 销毁(Destruction)

当 Spring 容器关闭时,Bean 进入销毁阶段。这个阶段包括以下关键步骤:

  • DisposableBean 接口和自定义销毁方法:如果 Bean 实现了 DisposableBean 接口,Spring 将调用其 destroy 方法。此外,如果配置了自定义的销毁方法,Spring 也会调用该方法。

这些步骤确保在销毁 Bean 之前执行必要的清理操作,释放资源。

@Override
public void destroy() throws Exception {
    System.out.println("DisposableBean: destroy called");
}

public void customDestroy() {
    System.out.println("Custom destroy-method: customDestroy called");
}

完整示例

为了更好地理解这些阶段,我们提供一个完整的示例,包括 Bean 类、BeanPostProcessor 和 Spring 配置。

Bean 类

package com.example.lifecycle;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;

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

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("BeanNameAware: setBeanName called with name " + beanName);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware: setBeanFactory called");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware: setApplicationContext called");
    }

    @PostConstruct
    public void init() {
        System.out.println("PostConstruct: init method called");
        this.name = "Initialized Bean";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean: afterPropertiesSet called");
    }

    public void customInit() {
        System.out.println("Custom init-method: customInit called");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean: destroy called");
    }

    public void customDestroy() {
        System.out.println("Custom destroy-method: customDestroy called");
    }
}

BeanPostProcessor

package com.example.lifecycle;

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

public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor: postProcessBeforeInitialization called for " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor: postProcessAfterInitialization called for " + beanName);
        return bean;
    }
}

Spring 配置

package com.example.lifecycle;

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

@Configuration
public class AppConfig {

    @Bean(initMethod = "customInit", destroyMethod = "customDestroy")
    public MyBean myBean() {
        MyBean myBean = new MyBean();
        myBean.setName("Test Bean");
        return myBean;
    }

    @Bean
    public CustomBeanPostProcessor customBeanPostProcessor() {
        return new CustomBeanPostProcessor();
    }
}

测试 Spring 配置

package com.example.lifecycle;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringLifecycleDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        MyBean myBean = context.getBean(MyBean.class);
        System.out.println("Using MyBean: " + myBean);

        context.close();
    }
}

参考链接

  1. Spring Framework Documentation
  2. TutorialsPoint: Spring Bean Life Cycle

在这里插入图片描述

标签:Spring,void,System,Bean,详解,println,public
From: https://blog.csdn.net/kaka_buka/article/details/139785424

相关文章

  • Spring (72)如何在Spring中使用缓存
    在Spring框架中,使用缓存是一种有效的方式来提高应用程序性能,减少数据库或者计算密集型操作的负担。Spring提供了一个声明式的缓存抽象,它允许开发者通过注解来简单地将缓存应用到应用程序中。下面我们将深入探讨Spring缓存的使用,结合源码解析和代码演示。1.SpringCache抽......
  • Spring (73)Spring项目中的事务管理最佳实践
    Spring项目中的事务管理是确保数据一致性和完整性的关键组成部分。Spring提供了一套灵活而强大的事务管理框架,允许开发者以声明式和编程式两种方式来管理事务。为了确保高效和安全的事务管理,遵循最佳实践是非常重要的。下面深入探讨Spring事务管理的最佳实践,并结合源码分析......
  • 优先级队列(堆)的知识点详解
    目录1.优先级队列1.1概念2.优先级队列的模拟实现2.1堆的概念2.2堆的存储方式2.3堆的创建2.3.1堆向下调整2.4堆的插入与删除2.4.1堆的插入2.4.2堆的删除3.常用接口介绍3.1PriorityQueue的特性3.2PriorityQueue常用接口介绍1.优先级队列1.1概念前......
  • Java:创建一个SpringBoot架构,并尝试访问一个简单的HTML页面:Hello HTML.创建SpringBoot
    下面我们开始教程:第一步:创建Maven工程我这里是Maven工程:之后再在pom文件导入SpringBoot坐标:注:我的平台版本是2020.1,有可能跟大家的不太一样,但创建项目大体类似。Maven即可。直接SpringBoot也可。Next下一步:取名项目名称:InfomanageNext下一步:Fish:然后进入pom.xml......
  • Java基于Vue+SpringBoot的交通管理在线服务系统
    传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装交通管理在线服务系统软件来发挥其高效地信息处理的作用,可以规范信息管理流程,让管理工作可以系统化和程序化,同时,交通......
  • 面试题(TCP/IP协议)详解三次握手
    TCP/IP协议中的三次握手我们首先来了解一下TCPTCP(TransmissionControlProtocol,传输控制协议)是一个面向连接的、可靠的、基于字节流的传输层通信协议。以下是TCP的一些主要特点:面向连接:在数据传输之前,TCP必须先建立连接(三次握手),在数据传输结束后,还要终止这个连接(......
  • 阐述Spring Security概念及其运用于实战
    SpringSecurity(安全校验)1.概述SpringSecurity是Spring项目组提供的安全服务框架,核心功能包括认证和授权.为系统提供了声明式安全访问控制功能,减少了为系统安全而编写大量重复代码的工作.在如今开发模式中,SpringSecurity已经成为Java程序员必备的一项技术,简化认......
  • 基于SpringBoot+Vue的网上花店系统设计与实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • 基于SpringBoot+Vue的小学生课外知识学习网站系统设计与实现(源码+lw+部署文档+讲解等
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • 【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
                   ......