java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Bean初始化

Spring Bean初始化及@PostConstruc执行顺序示例详解

作者:基础不牢,地动山摇

本文给大家介绍Spring Bean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

1. Bean初始化执行顺序

  1. 构造函数 - 首先调用Bean的构造函数

  2. 依赖注入 - 完成所有依赖项的注入(@Autowired等)

  3. @PostConstruct方法 - 执行带有@PostConstruct注解的方法

  4. InitializingBean的afterPropertiesSet() - 如果Bean实现了InitializingBean接口

  5. 自定义init方法 - 执行通过@Bean(initMethod="...")或XML配置中init-method指定的方法

@Component
public class ExampleBean implements InitializingBean {
    public ExampleBean() {
        System.out.println("1. 构造函数");
    }
    @Autowired
    public void setDependency(SomeDependency dep) {
        System.out.println("2. 依赖注入");
    }
    @PostConstruct
    public void postConstruct() {
        System.out.println("3. @PostConstruct方法");
    }
    @Override
    public void afterPropertiesSet() {
        System.out.println("4. InitializingBean的afterPropertiesSet()");
    }
    @Bean(initMethod = "customInit")
    public void customInit() {
        System.out.println("5. 自定义init方法");
    }
}

2. 成员变量初始化顺序

在Java中,类的成员变量(非静态成员变量)的初始化时机取决于其定义方式(直接赋值、构造器赋值、初始化块等)以及是否涉及依赖注入(如Spring框架)。

2.1 普通Java类(非Spring环境)

成员变量的初始化顺序和时机如下:

(1) 默认初始化(即初始分配内存)

(2) 显式初始化

public class MyClass {
    private int a = 10;          // 显式赋值
    private String s = "hello";  // 显式赋值
}
public class MyClass {
    private int x;
    {
        x = 20; // 初始化块赋值
    }
}

(3) 构造器初始化

public class MyClass {
    private int value;
    public MyClass() {
        this.value = 30; // 构造器赋值
    }
}

(4)完整顺序

默认值 → 显式赋值/初始化块 → 构造器赋值

2.2 Spring管理的Bean(依赖注入场景)

在Spring中,成员变量的初始化分为依赖注入普通成员变量初始化两部分:

(1) 普通成员变量

@Component
public class MyBean {
    private int count = 100;  // 显式赋值(Spring无关)
    public MyBean() {
        this.count = 200;     // 构造器覆盖
    }
}

(2) 依赖注入的成员变量

(3) 生命周期回调的影响

(4)关键区别总结

场景成员变量初始化时机
普通Java类默认值 → 显式赋值/初始化块 → 构造器赋值
Spring Bean(字段注入)默认值 → 显式赋值 → 构造器 → 依赖注入 → @PostConstruct
Spring Bean(构造器注入)与普通Java类相同,依赖通过构造器参数传入

2.3 final成员变量

public class MyClass {
    private final int x = 10;  // 声明时赋值
    private final int y;
    { y = 20; }  // 初始化块赋值
    private final int z;
    public MyClass() {
        z = 30;  // 构造器赋值
    }
}

2.4 常见面试问题

Q1: 为什么构造器里的赋值能覆盖显式赋值?

因为构造器是最后执行的,可以修改之前的值。

Q2: 以下代码的输出是什么?

public class Test {
    private int x = 10;
    { x = 20; }
    public Test() {
        System.out.println(x);
        x = 30;
    }
    public static void main(String[] args) {
        new Test(); // 输出?
    }
}
--
答案:20(显式赋值和初始化块先执行,构造器最后执行)。

到此这篇关于Spring Bean初始化及@PostConstruc执行顺序的文章就介绍到这了,更多相关Spring Bean初始化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文