IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring——Bean 的生命周期 -> 正文阅读

[Java知识库]Spring——Bean 的生命周期


一、Bean 的生命周期

??对于普通的 Java 对象,new 的时候会去创建对象,而当它没有任何引用的时候则被垃圾回收机制回收。相较于前者,由Spring IoC 容器托管的对象,它们的生命周期完全由容器控制。Spring 中每个 Bean 的生命周期如下:
在这里插入图片描述

  • 对于 ApplicationContext 容器,当容器启动结束后,实例化所有的 Bean。
  • 设置对象属性,即依赖注入,动态将依赖关系注入到对象中。
  • 紧接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware实例注入给 Bean。
  • 当经过上述几个步骤后,Bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过
    BeanPostProcessor接口实现。

该接口提供了两个函数:

  1. postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的 Bean 对象会被传递进来,我们就可以对这个 Bean 作任何处理。 这个函数会先于 InitialzationBean 执行,因此称为前置处理。 所有 Aware 接口的注入就是在这一步完成的。
  2. postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的 Bean 对象会被传递进来,我们就可以对这个 Bean 作任何处理。 这个函数会在 InitialzationBean 完成后执行,因此称为后置处理。
  • 当 BeanPostProcessor 的前置处理完成后就会进入以下阶段。
  • 这一阶段也可以在 Bean 正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前 Bean 对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。 若要使用它,我们需要让 Bean 实现该接口,并把要增加的逻辑写在该函数中。然后 Spring 会在前置处理完成后检测当前 Bean 是否实现了该接口,并执行 afterPropertiesSet 函数。

InitializingBean 接口只有一个函数:afterPropertiesSet()

  • 当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了 init-method 属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。 init-method本质上仍然使用了InitializingBean接口。
  • 通过给 destroy-method 指定函数,就可以在 Bean 销毁前执行指定的逻辑。

二、代码演示

项目结构如下:(红框中为代码演示使用到)
在这里插入图片描述

创建启动入口类:org.example.AppLifecycle

package org.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppLifecycle {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("lifecycle.xml");
        ((ClassPathXmlApplicationContext) context).close();
    }
}

Spring配置文件:在src/main/resources下,创建lifecycle.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"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.example.config"/>
</beans>

准备要进行生命周期管理的Bean对象,创建org.example.model.LifeCycleTest

package org.example.config;

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

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

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

    public void beanInit(){
        System.out.println("init-method: 注解是使用@Bean(initMethod=\"方法名\")的方式,xml是使用<bean init-method=\"方法名\" />");
    }

    @PostConstruct
    public void postConstruct(){
        System.out.println("@PostConstruct");
    }

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

    public void beanDestroy(){
        System.out.println("destroy-method: 注解是使用@Bean(destroyMethod=\"方法名\")的方式,xml是使用<bean destroy-method=\"方法名\" />");
    }

    @PreDestroy
    public void preDestroy(){
        System.out.println("@PreDestroy");
    }

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

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

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware");
    }

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

使用创建的配置类org.example.config.AppConfig

package org.example.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig implements BeanPostProcessor {

    @Bean(initMethod = "beanInit", destroyMethod = "beanDestroy")
    public LifeCycleTest lifeCycleTest(){
        return new LifeCycleTest();
    }

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

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

代码运行结果
在这里插入图片描述


三、主要步骤简述

  • 实例化 Bean:通过反射调用构造方法实例化对象。
  • 依赖注入:装配 Bean 的属性。
  • 实现了 Aware接口的 Bean,执行接口方法:如顺序执行 BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
  • Bean 对象初始化前,循环调用实现了 BeanPostProcessor 接口的预初始化方法(postProcessBeforeInitialization)。
  • Bean 对象初始化:顺序执行 @PostConstruct 注解方法、InitializingBean 接口方法、init-method 方法。
  • Bean 对象初始化后,循环调用实现了 BeanPostProcessor 接口的后初始化方法(postProcessAfterInitialization)。
  • 容器关闭时,执行 Bean 对象的销毁方法,顺序是:@PreDestroy 注解方法、DisposableBean 接口方法、destroy-method。

补充说明:第一步的实例化是指new对象,Spring的语义中说初始化Bean包含Bean生命周期中的初始化步骤。


  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:22:50  更:2022-03-22 20:25:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:14:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码