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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一篇文章了解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的创建、初始化和销毁过程,提高应用程序的灵活性和可维护性。

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.关系图

2.对于关系图的解释

2.1Spring Bean的生命周期:

1.通过XML、Java annotation(注解)以及Java Configuration(配置类)
等方式加载Spring Bean
2.BeanDefinitionReader:解析Bean的定义。在Spring容器启动过程中,

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

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

有点类似于XML解析

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

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

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

例如:

<bean id="" class="" scope=""> -----> BeanDefinition(id/class/scope)
4.BeanFactoryPostProcessor:是Spring容器功能的扩展接口。

注意:

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

在bean实例化之前执行的

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

属性填充、修改等操作

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

例如:

BeanFactory -> List<BeanDefinition>
BeanDefinition(id/class/scope/init-method)
<bean class="com.zking.spring02.biz.BookBizImpl"/>
foreach(BeanDefinition bean : List<BeanDefinition>){
   //根据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<BeanDefinition>集合
3.触发BeanFactoryPostProcessor,在Javabean初始化之前执行自己的业务
spring中的beanFactory,会通过List<BeanDefinition>集合遍历初始化所有的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<BeanDefinition> beans = new ArrayList<BeanDefinition>();
       //遍历解析
        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文件

<bean id="paramAction" class="com.lz.beanLife.ParamAction">
        <constructor-arg name="name" value="刘兵sb"></constructor-arg>
        <constructor-arg name="age" value="21"></constructor-arg>
        <constructor-arg name="hobby">
            <list>
                <value>抽烟</value>
                <value>烫头</value>
                <value>大保健</value>
            </list>
        </constructor-arg>
    </bean>
    <bean id="instanceFactory" class="com.lz.beanLife.InstanceFactory"
          scope="prototype" init-method="init" destroy-method="destroy"></bean>

3.响应图片单例模式

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

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

 

相关文章
|
1月前
|
XML 安全 Java
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
87 2
|
8天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
8天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
58 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
14天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
52 6
|
16天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
79 3
|
29天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
34 1
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
53 0
|
2月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
45 0