【Spring】Bean的生命周期与单例实现(一)

简介: 【Spring】Bean的生命周期与单例实现

6f1531d23d164f43aecfa1b428f6cefa.jpg

一、前言

1.1.介绍Spring框架和Bean的概念

嘿,朋友们!让我来给大家解析一下Spring框架和Bean的故事。

Spring框架就像是一个守护神,它包揽了Java应用程序的管理工作。它有点像一场超级派对组织者,让你能够轻松地管理和控制你的应用程序。它的目标是提供一种高效、灵活的方式来构建企业级应用程序。

那么Bean又是什么呢?Bean其实就是Spring框架中的真实对象。你可以把Bean想象成小伙伴们,在Spring框架的聚会上尽情闹腾!每个Bean都有自己的生命周期,就像人类一样有出生、成长、工作和退休等阶段。

首先,Bean的实例化就像我们的诞生一样,Spring负责创建Bean对象并把它们装载到容器中。接着,Bean的属性赋值就像我们在成长过程中学习新技能一样,它们被注入各种属性,变得丰富多彩。

接下来,是Bean的初始化阶段。就像我们开始工作前需要做准备一样,Bean也可以执行一些初始化操作,包括调用特定的初始化方法,或者通过Bean后置处理器做一些善后工作。

最后,当应用程序不再需要某个Bean时,它就像我们退休一样,可以执行一些销毁操作,例如释放资源、关闭数据库连接等。

总之,Spring框架和Bean就像是一个个聚会,这些小伙伴们在其中进出各个阶段,带来欢乐和成就。不过,别担心,Spring框架是一个负责任的派对组织者,它会确保每个Bean都会得到妥善地管理和照顾!

希望这个幽默风趣的介绍让你对Spring框架和Bean有了更好的理解!

二、Bean的实例化阶段

2.1.Bean的实例化过程

Bean的实例化过程是指将定义的Bean转换为可用的对象实例的过程。在Spring框架中,Bean的实例化可以分为以下几个阶段:

  1. 加载Bean的定义:使用配置文件(如XML配置文件)或注解方式将Bean的定义加载到容器中,由Spring框架负责解析。
  2. 实例化Bean:根据Bean的定义和配置信息,在内存中创建一个Bean的实例。这可以通过构造函数实例化、工厂方法实例化或通过对象反射等方式来进行。
  3. 属性赋值:对已经实例化的Bean对象进行属性赋值,包括基本数据类型、引用类型和集合类型等。属性可以通过注解或XML配置文件进行依赖关系的注入。
  4. Aware接口回调:如果Bean实现了Aware接口,Spring会自动检测并调用相应的回调方法,例如ApplicationContextAware接口可以获取ApplicationContext对象。
  5. 自定义初始化方法:如果Bean配置了初始化方法(可以通过注解或XML配置文件),Spring会在Bean完成属性赋值后调用该方法进行一些自定义的初始化操作。
  6. 后置处理器方法调用:如果配置了Bean后置处理器(BeanPostProcessor),Spring会自动检测并调用其相关方法进行额外的处理操作。
  7. Bean准备就绪:经过以上步骤,Bean实例化过程完成,可以被容器管理和使用。

2.2.介绍默认构造函数和工厂方法的使用

默认构造函数: 默认构造函数是一个无参的构造函数,它没有任何参数传递给对象创建过程。Spring会自动调用默认构造函数来实例化Bean对象。这种方式被广泛应用,可以方便地创建对象,并且不需要通过其他方式传递参数。例如:

public class MyBean {
    // 默认构造函数
    public MyBean() {
        // 初始化操作
    }
}

工厂方法: 工厂方法是一种通过特殊的方法来实例化Bean对象的方式。通常情况下,这个方法是在一个专门的工厂类中定义的。通过工厂方法,我们可以有更多的灵活性来创建Bean对象,并且可以自定义传递参数等操作。例如:

public class MyBeanFactory {
    // 工厂方法
    public static MyBean createMyBean() {
        // 创建Bean对象的逻辑
        return new MyBean();
    }
}

示例代码:展示如何使用默认构造函数和工厂方法来实例化Bean对象:

public class MyBean {
    private String message;
    // 默认构造函数
    public MyBean() {
        this.message = "Hello, world!";
    }
    // getter和setter方法
    public static MyBean createMyBean() {
        MyBean myBean = new MyBean();
        myBean.setMessage("Hello, Spring!");
        return myBean;
    }
}

三、Bean的初始化阶段

3.1.InitializingBean接口和@PostConstruct注解的使用

InitializingBean接口使用

该接口定义了一个方法afterPropertiesSet(),当Bean的所有属性都被设置好后,Spring容器会自动调用这个方法完成初始化操作。

import org.springframework.beans.factory.InitializingBean;
public class MyBean implements InitializingBean {
    private String message;
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean: Bean is being initialized with message: " + message);
    }
}

@PostConstruct注解使用

这个注解标记在Bean的初始化方法上,表示该方法会在Bean的属性设置完成后自动执行,完成Bean的初始化操作。

import javax.annotation.PostConstruct;
public class MyBean {
    private String message;
    public void setMessage(String message) {
        this.message = message;
    }
    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct: Bean is being initialized with message: " + message);
    }
}

需要注意的是,InitializingBean接口和@PostConstruct注解可以同时使用,但这两种方式并不是必须的,您可以根据需求选择其中之一进行Bean的初始化。

在Spring中,还可以通过配置文件来指定Bean的初始化方法,在XML配置文件中使用<bean>标签的init-method属性来设置。示例如下:

<bean id="myBean" class="com.example.MyBean" init-method="init">
    <property name="message" value="Hello World" />
</bean>

3.2.Bean的初始化方法配置和执行顺序

无论是使用InitializingBean接口、@PostConstruct注解还是XML配置文件,它们都可以用来指定Bean的初始化方法,并且执行顺序是相同的:首先执行属性的依赖注入,然后执行初始化方法。

public class Example {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        MyBean bean = context.getBean(MyBean.class);
        // Bean已经被初始化完成并且可以使用
        ((ConfigurableApplicationContext) context).close();
    }
}

在上述示例中,创建了一个ApplicationContext对象并加载了一个XML配置文件。通过调用getBean()方法获取MyBean的实例,Spring容器会自动进行属性的注入和初始化操作。当我们关闭应用程序的时候,可以调用((ConfigurableApplicationContext) context).close()方法关闭容器。

四、Bean的销毁阶段

4.1.DisposableBean接口和@PreDestroy注解的使用

DisposableBean接口使用

该接口定义了一个方法destroy(),当Bean需要被销毁时,Spring容器会自动调用这个方法完成清理工作。示例如下:

import org.springframework.beans.factory.DisposableBean;
public class MyBean implements DisposableBean {
    private String message;
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean: Bean is being destroyed with message: " + message);
    }
}

@PreDestroy注解使用

这个注解标记在Bean的销毁方法上,表示该方法会在需要销毁Bean时自动执行,完成清理工作。示例如下:

import javax.annotation.PreDestroy;
public class MyBean {
    private String message;
    public void setMessage(String message) {
        this.message = message;
    }
    @PreDestroy
    public void cleanup() {
        System.out.println("@PreDestroy: Bean is being destroyed with message: " + message);
    }
}

Bean的销毁也可以通过配置文件来指定Bean的销毁方法,在XML配置文件中使用<bean>标签的destroy-method属性来设置。示例如下:

<bean id="myBean" class="com.example.MyBean" destroy-method="cleanup">
    <property name="message" value="Goodbye World" />
</bean>

4.2.Bean的销毁方法配置和执行顺序

首先执行Bean的销毁方法,然后容器关闭或销毁。

public class Example {
    public static void main(String[] args) {
        // 创建并启动Spring容器
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取Bean实例
        MyBean bean = context.getBean(MyBean.class);
        // 使用Bean...
        // 手动关闭容器
        context.close();
    }
}

在上述示例中,我们创建了一个ApplicationContext对象并加载了一个XML配置文件。通过调用getBean()方法获取MyBean的实例,Spring容器会自动执行Bean的销毁方法。当我们手动关闭容器时,可以调用context.close()方法触发Bean的销毁。

相关文章
|
6天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
6天前
|
XML 前端开发 Java
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
9 0
|
6天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
6天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
9 0
|
6天前
|
存储 Java 对象存储
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
9 0
|
6天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
22 1
|
6天前
|
XML Java 数据格式
Spring Bean
【4月更文挑战第30天】Spring Bean
17 0
|
6天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
37 2
|
缓存 Java Spring
Spring 获取单例流程(三)
读完这篇文章你将会收获到 • Spring 何时将 bean 加入到第三级缓存和第一级缓存中 • Spring 何时回调各种 Aware 接口、BeanPostProcessor 、InitializingBean 等
109 0
|
缓存 Java Spring
Spring 获取单例流程(二)
读完这篇文章你将会收获到 • Spring 中 prototype 类型的 bean 如何做循环依赖检测 • Spring 中 singleton 类型的 bean 如何做循环依赖检测
66 0