当前位置: 代码网 > it编程>编程语言>Java > Spring Bean初始化及@PostConstruc执行顺序示例详解

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

2025年07月24日 Java 我要评论
1. bean初始化执行顺序构造函数- 首先调用bean的构造函数依赖注入- 完成所有依赖项的注入(@autowired等)@postconstruct方法- 执行带有@postconstruct注解

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) 默认初始化(即初始分配内存)

  • 时机:对象实例化时(new关键字调用构造器之前)。

  • 规则:所有成员变量先被赋予默认值(int0booleanfalse,引用类型→null等)。

(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) 普通成员变量

  • 初始化规则与普通java类一致(默认值 → 显式赋值 → 构造器)。

  • 示例

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

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

  • 时机:在bean实例化后,由spring容器通过反射或setter方法注入。

    • 字段注入(@autowired):
      在构造器和显式赋值之后,通过反射直接注入。

      @component
      public class mybean {
          @autowired
          private dependency dependency; // spring在对象构造后注入
      }
    • 构造器注入
      在实例化时通过构造器参数注入(等同于普通java的构造器赋值)。

      @component
      public class mybean {
          private final dependency dependency;
          public mybean(dependency dependency) {
              this.dependency = dependency; // 构造时注入
          }
      }

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

  • @postconstruct方法会在依赖注入完成后执行,此时所有成员变量(包括注入的依赖)已就绪:

    @component
    public class mybean {
        @autowired
        private dependency dependency;
        @postconstruct
        public void init() {
            system.out.println(dependency); // 依赖已注入
        }
    }

(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初始化内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com