一篇文章了解Java spring中bean的生命周期!

一.介绍在Java spring中bean的生命周期

1.什么是 Bean?

我们来看下 Spring Framework 的官方文档:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

简而言之,bean 是由 Spring IoC 容器实例化、组装和管理的对象。

2.Java spring中bean的生命周期是什么?

在Java Spring中,Bean的生命周期是指一个Bean从被实例化到最终被销毁的整个过程。Spring容器负责管理Bean的生命周期,并在特定时机触发相应的回调方法。

3.Bean的生命周期包括以下几个关键阶段:

  1. 实例化(Instantiation):在这个阶段,Spring容器根据配置或注解创建Bean的实例对象。

  2. 属性赋值(Population):在实例化后,Spring容器将通过依赖注入(Dependency Injection)或属性设置将相关属性值传递给Bean。

  3. 初始化回调(Initialization Callback):在属性赋值完成后,如果Bean实现了InitializingBean接口,Spring容器会调用其afterPropertiesSet()方法。同时,还可以通过在配置文件中指定init-method来指定初始化方法。

  4. 使用中(In Use):在初始化完毕后,Bean可以被应用程序正常使用,执行相应的业务逻辑。

  5. 销毁回调(Destruction Callback):当Bean不再需要时,Spring容器会在适当的时候触发销毁回调方法。如果Bean实现了DisposableBean接口,Spring容器会调用其destroy()方法。另外,也可以通过在配置文件中指定destroy-method来指定销毁方法。

需要注意的是,并非所有Bean都需要实现InitializingBeanDisposableBean接口或通过配置指定初始化和销毁方法。这些操作是可选的,可以根据需要选择是否使用。此外,还可以使用注解驱动的方式,如@PostConstruct@PreDestroy注解,来定义初始化和销毁方法。

通过生命周期回调方法,我们可以在Bean的不同阶段执行自定义逻辑,例如进行初始化设置、资源加载、连接数据库等。Spring的生命周期管理能够帮助我们更好地控制Bean的创建、初始化和销毁过程,提高应用程序的灵活性和可维护性。

一篇文章了解Java spring中bean的生命周期!_第1张图片

 4.Java spring中bean的生命周期会使用到应用场景

在Java Spring中,Bean的生命周期可以应用于以下场景:

  1. 初始化配置:在Bean实例化和初始化阶段,可以执行一些初始化配置的操作,例如加载配置文件、连接数据库、初始化缓存等。

  2. 依赖注入:在Bean的属性赋值阶段,可以进行依赖注入,将其他Bean所需要的依赖项自动注入到目标Bean中。

  3. 自定义逻辑:通过在Bean的生命周期中定义回调方法,可以执行自定义的业务逻辑。例如,在初始化前后执行一些额外的逻辑操作,或者在销毁前后进行资源清理。

  4. 资源管理:可以在Bean的销毁阶段,释放占用的资源,如关闭数据库连接、释放文件句柄、停止定时任务等。

  5. AOP(面向切面编程):可以利用Bean的生命周期回调方法,在特定的时间点织入AOP切面逻辑,例如在初始化之后执行一些切面操作。

  6. 第三方库集成:当使用某些第三方库时,可能需要在Bean的生命周期中进行初始化和销毁操作,以确保库的正确使用和释放。

总结来说,Java Spring中Bean的生命周期可以应用于初始化配置、依赖注入、自定义逻辑、资源管理、AOP和第三方库集成等场景。它可以帮助我们更好地管理和控制Bean的创建、初始化和销毁过程,提高应用程序的可维护性和可扩展性。 


二. Java spring 中常用接口说明

2.1 BeanNameAware

该接口只有一个方法 setBeanName(String name),用来获取 bean 的 id 或者 name。

2.2 BeanFactoryAware

该接口只有一个方法 setBeanFactory(BeanFactory beanFactory),用来获取当前环境中的 BeanFactory。

2.3 ApplicationContextAware

该接口只有一个方法 setApplicationContext(ApplicationContext applicationContext),用来获取当前环境中的 ApplicationContext。

2.4 InitializingBean

该接口只有一个方法 afterPropertiesSet(),在属性注入完成后调用。

2.5 DisposableBean

该接口只有一个方法 destroy(),在容器销毁的时候调用,在用户指定的 destroy-method 之前调用。

2.6 BeanPostProcessor

该接口有两个方法:

postProcessBeforeInitialization(Object bean, String beanName):在初始化之前调用此方法
postProcessAfterInitialization(Object bean, String beanName):在初始化之后调用此方法
通过方法签名我们可以知道,我们可以通过 beanName 来筛选出我们需要进行个性化定制的 bean。

2.7 InstantiationAwareBeanPostProcessor

该类是 BeanPostProcessor 的子接口,常用的有如下三个方法:

postProcessBeforeInstantiation(Class beanClass, String beanName):在bean实例化之前调用
postProcessProperties(PropertyValues pvs, Object bean, String beanName):在bean实例化之后、设置属性前调用
postProcessAfterInstantiation(Class beanClass, String beanName):在bean实例化之后调用

三.如何去验证生命周期

1.关系图

一篇文章了解Java spring中bean的生命周期!_第2张图片

一篇文章了解Java spring中bean的生命周期!_第3张图片

 2.对于关系图的解释

2.1Spring Bean的生命周期:

1.通过XML、Java annotation(注解)以及Java Configuration(配置类)

等方式加载Spring Bean

2.BeanDefinitionReader:解析Bean的定义。在Spring容器启动过程中,

会将Bean解析成Spring内部的BeanDefinition结构;

理解为:将spring.xml中的标签转换成BeanDefinition结构

有点类似于XML解析

3.包含了很多属性和方法。例如:id、class(类名)、

scope、ref(依赖的bean)等等。其实就是将bean(例如)的定义信息

存储到这个对应BeanDefinition相应的属性中

例如:

 -----> BeanDefinition(id/class/scope)

4.BeanFactoryPostProcessor:是Spring容器功能的扩展接口。

注意:

4.1BeanFactoryPostProcessor在spring容器加载完BeanDefinition之后,

在bean实例化之前执行的

4.2对bean元数据(BeanDefinition)进行加工处理,也就是BeanDefinition

属性填充、修改等操作

5.BeanFactory:bean工厂。它按照我们的要求生产我们需要的各种各样的bean。

例如:

BeanFactory -> List

BeanDefinition(id/class/scope/init-method)



foreach(BeanDefinition bean : List){

   //根据class属性反射机制实例化对象

   //反射赋值设置属性

}

6.Aware感知接口:在实际开发中,经常需要用到Spring容器本身的功能资源

例如:BeanNameAware、ApplicationContextAware等等

BeanDefinition 实现了 BeanNameAware、ApplicationContextAware

7.BeanPostProcessor:后置处理器。在Bean对象实例化和引入注入完毕后,

在显示调用初始化方法的前后添加自定义的逻辑。(类似于AOP的绕环通知)

前提条件:如果检测到Bean对象实现了BeanPostProcessor后置处理器才会执行

Before和After方法

BeanPostProcessor

1)Before

2)调用初始化Bean(InitializingBean和init-method,Bean的初始化才算完成)

3)After

完成了Bean的创建工作

8)destory:销毁

 3.spring容器管理javabean的初始化过程

1.xml/annotation/configuation 配置JavaBean
2.BeanDefinitionReader解析配置的Javabean得到BeanDefinition最终得到List集合
3.触发BeanFactoryPostProcessor,在Javabean初始化之前执行自己的业务
spring中的beanFactory,会通过List集合遍历初始化所有的Javabean对象
如果javabean需要调动spring上下文的资源,那么需要实现Aware感知接口 
4.如果自己的javabean以及初始化好了,还需要扩展功能,那么还需要借助BeanFactoryPostProcessor来实现 

4.通过IDEA模拟测试数据

1.建立一个模拟数据(并且解析spring配置的xml文件)

package com.lz.beanLife;

import org.springframework.beans.factory.config.BeanDefinition;

import java.util.ArrayList;
import java.util.List;

/**
 * @author lz
 * @create 2023-08-18 14:39
 */
public class demo1 {
    public static void main(String[] args) {
        //解析spring-context 内容
        List beans = new ArrayList();
       //遍历解析
        for (BeanDefinition  bean: beans) {
            String beanClassName = bean.getBeanClassName();
            try {
                Class.forName(beanClassName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }

    }
}
class   User{

}
class   Person{
     private   int  pid;
     private   String  pname;
     private   String  sex;
     private    User   user;

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Person(int pid, String pname, String sex) {
        this.init();
        this.pid = pid;
        this.pname = pname;
        this.sex = sex;
    }


    public Person() {
    }

    @Override
    public String  toString() {
        return "Person{" +
                "pid=" + pid +
                ", pname='" + pname + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
   public void init() {

    }
}

2.spring需要配置的xml文件


        
        
        
            
                抽烟
                烫头
                大保健
            
        
    

    

3.响应图片单例模式

一篇文章了解Java spring中bean的生命周期!_第4张图片

 一篇文章了解Java spring中bean的生命周期!_第5张图片

5.总结spring中Javabean是单例还是多例

1.默认是单例,但是可以配置多例
2.单例  的优点是节约内存,弊端有变量污染!
多例  的优点是无变量污染,弊端消耗内存!
3.单例javabean是跟着spring上下文初始化的,同生共死!
多例javabean使用才会初始化

 

你可能感兴趣的:(spring,java,spring,开发语言,maven,bean,intellij-idea,面试)