Spring源码解析之Bean的生命周期

Spring源码解析之Bean的生命周期

在 Spring 容器启动时,会加载配置文件中的 bean 定义信息并通过反射机制创建 bean 实例,然后将这些 bean 实例化、初始化,最后将这些 bean 注册到 Spring 容器中,供外部调用。这个过程就是 Spring 容器管理 bean 的生命周期。在本文中,我们将探索 Spring 容器如何管理 bean 的生命周期。

1. bean 的生命周期

bean 的生命周期经过以下阶段:

  1. 实例化 (Instantiation)
  2. 属性赋值 (Populate properties)
  3. 初始化 (Initialization)
  4. 销毁 (Destruction)

下面我们将介绍这些阶段。

1.1 实例化

根据 bean 配置信息,Spring 容器会使用反射机制实例化一个 bean 对象。可以使用构造函数实例化对象,也可以使用工厂方法实例化对象。例如,下面的配置使用构造函数实例化对象:

<bean id="exampleBean" class="com.example.ExampleBean"/>

可以使用工厂方法实例化对象:

<bean id="exampleBean" factory-method="createInstance" class="com.example.ExampleBeanFactory"/>

其中,ExampleBeanFactory 是一个工厂类,createInstance 是工厂类中的工厂方法。

1.2 属性赋值

在实例化 bean 后,Spring 容器会调用 setter 方法设置 bean 的属性值。可以通过 XML 配置文件、Java 配置方式或自动扫描等方式进行属性注入。例如,下面的配置设置属性值:

<bean id="person" class="com.example.Person">
    <property name="name" value="张三" />
    <property name="age" value="20" />
</bean>

在上面的配置中,Person 类有两个属性 nameage,通过 <property> 元素设置属性值。

1.3 初始化

在属性赋值完成后,Spring 容器会调用 InitializingBean 接口中的 afterPropertiesSet() 方法或 @PostConstruct 注解标注的方法执行 bean 的初始化。可以在初始化方法中完成一些准备工作。例如,下面的代码是一个初始化方法:

public class ExampleBean implements InitializingBean {

    private String name;

    private int age;

    ...

    @Override
    public void afterPropertiesSet() throws Exception {
        // 执行初始化操作
        ...
    }
}

或者,使用 @PostConstruct 注解标注初始化方法:

public class ExampleBean {

    private String name;

    private int age;

    ...

    @PostConstruct
    public void init() {
        // 执行初始化操作
        ...
    }
}

1.4 销毁

在容器关闭时,Spring 容器会调用 DisposableBean 接口中的 destroy() 方法或 @PreDestroy 注解标注的方法销毁 bean。

例如,下面的代码是销毁方法的示例:

public class ExampleBean implements DisposableBean {

    private String name;

    private int age;

    ...

    @Override
    public void destroy() throws Exception {
        // 执行销毁操作
        ...
    }
}

或者,使用 @PreDestroy 注解标注销毁方法:

public class ExampleBean {

    private String name;

    private int age;

    ...

    @PreDestroy
    public void destroy() {
        // 执行销毁操作
        ...
    }
}

2. 示例说明

我们通过示例来说明 bean 生命周期的过程。

首先,在 src/main/java/com/example 目录下新建 Person.java 文件,内容如下:

package com.example;

public class Person {

    private String name;

    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }

    public void sayHello() {
        System.out.println("Hello, I'm " + name + ", " + age + " years old.");
    }
}

然后,在 src/main/resources 目录下新建 applicationContext.xml 文件,内容如下:

<bean id="person" class="com.example.Person">
    <property name="name" value="张三" />
    <property name="age" value="20" />
</bean>

接下来,在 src/main/java/com/example 目录下新建 Main.java 文件,内容如下:

package com.example;

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

public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = context.getBean("person", Person.class);
        person.sayHello();
        ((ClassPathXmlApplicationContext) context).close();
    }
}

运行 Main 类,控制台输出:

Hello, I'm 张三, 20 years old.

在这个示例中,Person 类有两个属性 nameage,在 applicationContext.xml 中通过 <property> 元素设置属性值。在 Main 类中,通过 ApplicationContext 加载 applicationContext.xml 配置文件,并从中获取 Person 实例,调用 sayHello() 方法输出信息。在程序结束时,使用 close() 方法关闭容器,销毁 bean。

除了 XML 配置方式,还可以使用注解方式或 Java 配置方式构建 bean。例如,下面的代码是使用注解方式构建 bean:

package com.example;

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

import org.springframework.stereotype.Component;

@Component
public class ExampleBean {

    private String name;

    private int age;

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

    public void setAge(int age) {
        this.age = age;
    }

    @PostConstruct
    public void init() {
        System.out.println("Initializing ExampleBean...");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("Destroying ExampleBean...");
    }
}

使用 Java 配置方式构建 bean:

package com.example;

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

@Configuration
public class AppConfig {

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }
}

我们可以在项目中使用不同的方式来构建 bean,并了解它们的生命周期信息,从而更好地理解 Spring 容器对 bean 的管理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring源码解析之Bean的生命周期 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • Java中的封装是什么?

    Java中的封装(Encapsulation)是一种面向对象编程(OOP)中常见的原则之一,它是OOP中三大特征(封装、继承和多态)之一。 封装是指将一个对象的属性和方法进行私有化,使其不被外部直接访问和修改。目的在于隐藏对象的具体实现细节,增加代码的可读性、可维护性和安全性。在Java中,使用关键字private来实现封装。 下面以一个银行账户类Accou…

    Java 2023年4月27日
    00
  • 使用JDBC工具类实现简单的登录管理系统

    使用JDBC工具类实现简单的登录管理系统需要以下步骤: 准备工作 在项目中引入JDBC依赖,如使用Maven引入jdbc依赖: <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> &l…

    Java 2023年6月16日
    00
  • Java如何将Excel数据导入到数据库

    下面我将为你详细解释如何使用Java将Excel数据导入到数据库。整个过程可以分为以下几个步骤: 导入相关依赖库 要想使用Java将Excel数据导入到数据库,我们需要使用Apache的POI库来读取和解析Excel文件,以及使用数据库的JDBC驱动。因此需要在项目中导入以下两个依赖库: <dependency> <groupId>o…

    Java 2023年5月20日
    00
  • 实例解析Java的Jackson库中的数据绑定

    实例解析Java的Jackson库中的数据绑定 Jackson是Java平台领先的开源JSON(JavaScript Object Notation)处理库,它有着出色的性能和易用性,并且支持流式解析和生成JSON数据。Jackson提供了诸如JsonNode、ObjectMapper、ObjectReader、ObjectWriter等API来处理JSON…

    Java 2023年5月26日
    00
  • Java中List排序的三种实现方法实例

    Java中List排序的三种实现方法实例 在Java中List是一个非常常用的集合类,其用于存储和操作一组具有序列特性的对象。其中List中提供了sort()方法,用于对其中的元素进行排序操作。本文将会详细讲解Java中List排序的三种实现方法。 一、使用Collections.sort() Collections是Java中一个非常重要的集合工具类,其中…

    Java 2023年5月26日
    00
  • 一个例子带你看懂Java中synchronized关键字到底怎么用

    让我来详细讲解“一个例子带你看懂Java中synchronized关键字到底怎么用”的完整攻略。 完整攻略 什么是synchronized关键字? synchronized是Java中的一个关键字,用于线程之间的同步操作。它的作用是给代码块或方法加锁,保证同一时刻只有一个线程可以进入被加锁的代码块或方法。 synchronized关键字的用法 synchro…

    Java 2023年5月26日
    00
  • java.lang.NoClassDefFoundError错误解决办法

    下面我将详细讲解如何解决”java.lang.NoClassDefFoundError”错误。 1. 什么是”java.lang.NoClassDefFoundError”错误 “java.lang.NoClassDefFoundError”错误是Java程序编译或运行过程中遇到的一个常见错误,表示无法找到相关类的定义。它通常是由以下原因导致的: 缺少相关类…

    Java 2023年5月20日
    00
  • Java Optional实践(小结)

    Java Optional实践(小结) 什么是Java Optional? Optional 是 Java 8 引入的一个新特性,可以作为一种容器,对空值的处理提供更为优美的解决方案。 通常情况下我们在使用 Java 的时候经常会遇到 NullPointerException,就比如一个变量为 null,我们调用其方法时就可能会抛出该异常。而 Optiona…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部