Spring创建Bean的生命周期详析

首先,Spring中Bean创建的生命周期分为以下几个步骤:

  1. Bean实例化
  2. 属性设置(依赖注入)
  3. Aware回调(例如BeanNameAware、BeanFactoryAware)
  4. BeanPostProcessor前置处理
  5. 初始化方法调用
  6. BeanPostProcessor后置处理

下面我们来一步步分析每一个步骤。

Bean实例化

在Spring容器中,Bean实例化通常有两个过程:实例化和初始化。实例化是创建Bean实例的过程,通常是通过构造函数或工厂方法进行的。初始化是为Bean设置属性,通常是通过依赖注入完成的。

对于实例化过程,我们来看一个示例,假设有一个类叫做MyBean

public class MyBean {
    public MyBean() {
        System.out.println("MyBean: 实例化");
    }
}

在Spring容器中,使用如下方式配置 MyBean:

<bean id="myBean" class="com.example.MyBean"/>

当我们启动应用程序时,会看到输出 MyBean: 实例化,这表示MyBean已经成功实例化。

属性设置(依赖注入)

在实例化Bean后,Spring会为Bean注入属性,也就是依赖注入。依赖注入有多种方式,例如:

  • 构造函数注入
  • Setter方法注入
  • 属性注入

下面我们以Setter方法注入为例,假设有另外一个类叫做MyBeanDep,它需要注入到MyBean中作为一个依赖:

public class MyBeanDep {
    public void init() {
        System.out.println("MyBeanDep: 初始化");
    }
}

我们将MyBeanDep注入到MyBean中:

<bean id="myBeanDep" class="com.example.MyBeanDep"/>

<bean id="myBean" class="com.example.MyBean">
    <property name="myBeanDep" ref="myBeanDep"/>
</bean>

这里我们使用<property>标签来设置属性,其中name属性指定了要设置的属性名,ref属性指定了要注入的依赖Bean的ID。

Aware回调

Aware接口是Spring提供的一组接口,实现这些接口的Bean可以获取Spring容器的一些资源,例如Bean的名称、BeanFactory等。 例如,我们可以实现BeanNameAware接口,获取自己在Spring容器中的名称:

public class MyBean implements BeanNameAware {
    private String name;

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

在Spring容器中,我们这样配置MyBean:

<bean id="myBean" class="com.example.MyBean"/>

启动应用程序时,Spring会调用setBeanName方法,并将MyBean在容器中的名称传入。

BeanPostProcessor前置处理

BeanPostProcessor是Spring提供的一个接口,可以用来在Bean实例化、初始化过程中对Bean进行处理。Spring内置了许多实现了BeanPostProcessor接口的类,例如ApplicationContextAwareProcessor、AutowiredAnnotationBeanPostProcessor等。

例如,我们可以实现一个简单的BeanPostProcessor,打印出Bean的实例化和初始化方法被调用的时间:

public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        System.out.println(name + ": 处理前置处理,当前时间:" + new Date());
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        System.out.println(name + ": 处理后置处理,当前时间:" + new Date());
        return bean;
    }
}

在Spring容器中,我们这样配置Bean:

<bean id="myBeanPostProcessor" class="com.example.MyBeanPostProcessor"/>

<bean id="myBean" class="com.example.MyBean">
    <property name="myBeanDep" ref="myBeanDep"/>
</bean>

启动应用程序,我们可以看到输出类似于以下内容:

myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:40:03 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:40:04 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:40:04 CST 2021
MyBeanDep: 初始化
myBean: 处理后置处理,当前时间: Thu Aug 19 23:40:04 CST 2021

初始化方法调用

初始化方法是Spring容器为Bean设置完属性、完成Aware回调、执行完BeanPostProcessor前置处理后调用的方法。 在Spring中,Bean可以通过实现InitializingBean接口或在配置文件中使用init-method属性来指定初始化方法。

例如,我们在MyBean类中定义初始化方法:

public class MyBean implements InitializingBean {
    public void afterPropertiesSet() throws Exception {
        System.out.println("MyBean: 初始化");
    }
}

在Spring容器中,我们这样配置Bean:

<bean id="myBean" class="com.example.MyBean">
    <property name="myBeanDep" ref="myBeanDep"/>
    <init-method>afterPropertiesSet</init-method>
</bean>

启动应用程序,我们可以看到输出类似于以下内容:

myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:50:29 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:50:30 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:50:30 CST 2021
MyBeanDep: 初始化
MyBean: 初始化
myBean: 处理后置处理,当前时间: Thu Aug 19 23:50:30 CST 2021

BeanPostProcessor后置处理

BeanPostProcessor后置处理是在Bean初始化方法调用后执行的。有时候我们需要在Bean初始化后做一些其他的操作,例如缓存Bean或者检查Bean状态是否正确。

例如,我们实现一个BeanPostProcessor,输出Bean是否已正确初始化:

public class MyBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        if (bean instanceof MyBean) {
            MyBean myBean = (MyBean) bean;
            if (myBean.getMyBeanDep() != null) {
                System.out.println("MyBean已正确初始化!");
            } else {
                System.out.println("MyBean未正确初始化!");
            }
        }
        return bean;
    }
}

启动应用程序,我们可以看到输出类似于以下内容:

myBeanPostProcessor: 处理前置处理,当前时间: Thu Aug 19 23:56:47 CST 2021
myBean: 实例化
myBean: 处理前置处理,当前时间: Thu Aug 19 23:56:48 CST 2021
myBean: 处理后置处理,当前时间: Thu Aug 19 23:56:48 CST 2021
MyBeanDep: 初始化
MyBean已正确初始化!
myBean: 处理后置处理,当前时间: Thu Aug 19 23:56:48 CST 2021

通过上述示例,我们可以清晰了解Spring中Bean创建的完整生命周期及其每一个步骤。

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

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

相关文章

  • MySQL优化案例之隐式字符编码转换

    MySQL优化案例之隐式字符编码转换是一个涉及MySQL字符集和编码的优化技巧,能够帮助开发者避免隐式字符编码转换带来的性能影响。 以下是MySQL优化案例之隐式字符编码转换的完整攻略: 背景和问题 MySQL中字符集和编码是非常重要的概念,不同的字符集和编码对查询和存储的性能影响很大,甚至会带来莫名其妙的问题。在MySQL中,如果查询语句中涉及到多个字段或…

    other 2023年6月25日
    00
  • Android下拉刷新上拉加载控件(适用于所有View)

    Android下拉刷新上拉加载控件 在 Android 开发中,下拉刷新和上拉加载是一种常用的业务需求。为了方便开发者使用,有很多第三方控件可以供我们使用。本文将介绍一款适用于所有 View 的下拉刷新上拉加载控件。 控件介绍 本控件基于 Android 的 NestedScrolling 机制来实现下拉刷新和上拉加载,可以使用在 RecyclerView、…

    other 2023年6月25日
    00
  • Win10一周年更新14328下载迅雷发生崩溃怎么办?官方解决方案出炉

    Win10一周年更新14328下载迅雷发生崩溃怎么办? 如果你在下载Win10一周年更新14328时,使用迅雷下载软件遭遇了崩溃,那么你需要根据以下步骤解决这个问题: 首先,打开迅雷应用,并点击“工具”选项卡。 接着,点击“选项”按钮,并选择“高级”选项卡。 在“高级”选项卡下,找到“系统设置”一栏,并且在“系统设置”下方的“文件系统自动监控”选项卡中,取消…

    other 2023年6月26日
    00
  • C++逆向分析移除链表元素实现方法详解

    C++逆向分析移除链表元素实现方法详解 简介 链表是一种常见的数据结构,其中每个节点除了存储本身数据外,还包含一个指向下一节点的指针。链表的一个常见操作是删除其中的元素,本文将详细介绍 C++ 逆向分析移除链表元素的实现方法。 实现方法 迭代法 迭代法是最简单的链表元素移除方法,它的思路是:从链表头开始遍历链表,当遇到某个节点的值等于给定值时,将该节点从链表…

    other 2023年6月27日
    00
  • 系统安装时文件系统的选择

    下面是关于“系统安装时文件系统的选择”的完整攻略,并包含两条示例说明。 概述 在进行操作系统安装时,选择适当的文件系统是非常重要的。文件系统是在磁盘上组织和管理数据的方法。不同的文件系统具有不同的性能、安全性和可用性,因此需要根据个人需求进行选择。 常见的文件系统 下面是一些常见的文件系统及其特性: NTFS(New Technology File Syst…

    other 2023年6月27日
    00
  • 关于javascript作用域的常见面试题分享

    关于JavaScript作用域的常见面试题分享 JavaScript作用域是指变量、函数和对象的可访问范围。在面试中,经常会涉及到与JavaScript作用域相关的问题。下面是一些常见的面试题以及它们的详细解答。 1. 什么是作用域? 作用域是指在程序中定义变量的区域,它决定了变量的可见性和生命周期。JavaScript中有全局作用域和局部作用域两种。 全局…

    other 2023年7月29日
    00
  • Win11提示0x800704cf错误怎么办? Win11不能访问网络位置的解决方法

    Win11提示0x800704cf错误怎么办? 在 Win11 操作系统中,有用户反馈遭遇到了“Win11提示0x800704cf错误”的问题。这个错误表示操作系统在尝试访问网络位置时遇到了问题。下面是解决此问题的步骤。 步骤1:检查网络设置 首先要检查的是计算机的网络设置。要确保网络设置正确,以允许计算机访问 Internet。以下是详细步骤。 1.1 打…

    other 2023年6月27日
    00
  • 告别DNS劫持,一文读懂DoH

    告别DNS劫持,一文读懂DoH 在使用网络的过程中,我们经常会遇到DNS劫持的问题,这种情况下,我们所访问的网站可能并非我们想要的网站,而是另一个被劫持的站点。为了解决这个问题,现有一项技术正在得到越来越多的关注和应用,那就是DNS over HTTPS(简称DoH)。 什么是DNS over HTTPS? DNS over HTTPS(DoH)是一种使用H…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部