Spring Bean初始化及@PostConstruc执行顺序

目录

1. Bean初始化执行顺序

2. 成员变量初始化顺序

2.1 普通Java类(非Spring环境)

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

(2) 显式初始化

(3) 构造器初始化

(4)完整顺序

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

(1) 普通成员变量

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

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

(4)关键区别总结

2.3 final 成员变量 

2.4 常见面试问题


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. 构造函数");}@Autowiredpublic void setDependency(SomeDependency dep) {System.out.println("2. 依赖注入");}@PostConstructpublic void postConstruct() {System.out.println("3. @PostConstruct方法");}@Overridepublic 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 {@Autowiredprivate 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 {@Autowiredprivate Dependency dependency;@PostConstructpublic 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(显式赋值和初始化块先执行,构造器最后执行)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90467.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webRTC合并本地源码修改和官方更新

一、总体思路:基于 Git 分支管理改动origin/main 是官方 WebRTC 主干(来自 webrtc.googlesource.com)。my/webrtc 是你自己开发和修改的分支。每次 Google 更新 WebRTC,你从 origin/main 拉新代码,再把 my/webrtc 分支…

c++注意点(12)----设计模式(生成器)

创建型模式生成器模式(Builder Pattern)是一种创建型设计模式,它专注于将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。就像是做饭,你可以自己慢慢做,各个步骤自己选择。而使用生成…

[特殊字符] VLA 如何“绕过”手眼标定?—— 当机器人学会了“看一眼就动手”

🔮 VLA 如何“绕过”手眼标定?—— 当机器人学会了“看一眼就动手” 作者:石去皿 发布时间:2025年7月 在传统机器人系统中,“手眼标定”是每一个工程师都绕不开的课题。 你必须精确测量相机和机械臂之间的空间变换关系…

《Maven 核心基础笔记(第一天)》

1.说明maven软件依赖管理和项目构建功能maven是为Java项目工作的 功能体现:依赖管理,项目构建 依赖管理:我们只需要写配置文件(pom.xml),maven就会帮我们下载依赖,并且也会下载依赖的依赖。 项目构建:项目源…

Yolo底层原理学习(V1~V3)(第一篇)

一,卷积后的特征图大小计算众所周知,提到深度学习,必不可少的会提及卷积,那么如何计算卷积之后的图片大小呢?下图呈现:如图, 我们令FH,FW为原图像的长度FH*FW。P为padding的长度&…

前端开发项目性能瓶颈分析

1. 使用 rollup-plugin-visualizer 分析构建 借助 rollup-plugin-visualizer 插件,可以分析通过 rollup 构建出的产物内容,并生成可视化图表,帮助你分析打包后的文件大小以及各个模块的占用情况。 1.1. 安装插件 你需要在你的项目中安装 r…

ExoData.h - OpenExo

ExoData.h文件定位源代码1. 头文件依赖2. 核心类声明3. 主要成员函数关节遍历工具关节与配置相关数据/状态操作控制参数/校准4. 主要成员变量总结文件定位 位置:src/ExoData.h 作用:定义 ExoData 类,作为 Exo 系统全局数据的核心容器。它将设…

缓存HDC内容用于后续Direct2D绘制.

思路&#xff1a;把HDC里的内容保存到Direct2D格式的位图里&#xff0c;后续直接调用 renderTarget->DrawBitmap即可。本例中&#xff0c;位图将保存为类的字段。本例中 COM 接口指针皆使用 com_ptr&#xff0c;这是 WinRT 的 COM 智能指针类&#xff0c;com_ptr<I>::…

“抓了个寂寞”:一次实时信息采集的意外和修复

1. 那天下午&#xff0c;舆情系统“迟到”了 那天下午&#xff0c;公司运营那边突然在群里喊&#xff1a;“XX事件都快上热搜榜前十了&#xff0c;咱们系统咋没反应&#xff1f;” 我愣了几秒&#xff0c;立马翻后台日志、爬虫执行记录&#xff0c;结果一查&#xff0c;还真有点…

数据结构之迪杰斯特拉算法

前言&#xff1a;前面两篇文章介绍了生成图的最小生成树的算法&#xff0c;接下来两篇文章会介绍图的最短路径的算法&#xff0c;迪杰斯特拉算法和弗洛伊德算法。迪杰斯特拉算法是用来计算一个点到其他所有点的最短路径&#xff0c;这个点称之为源点。 一、实现流程 回忆一下…

技术文档 | OpenAI 的 Kafka 演进之路与 Pulsar 迁移潜力

导读ChatGPT 用户量指数级暴涨&#xff0c;OpenAI 的 Kafka 集群在一年内增长 20 倍至 30 个集群[1]&#xff0c;其 Kafka 架构面临日均千亿级消息&#xff08;峰值 QPS 800万/秒&#xff09; 的压力。这揭示了一个关键事实&#xff1a;OpenAI 的成功不只依赖模型&#xff0c;更…

【bug】 jetson上opencv无法录制h264本地视频

在Jetson Orin NX上无法使用opencv直接录制h264/h265视频流&#xff08;h264格式的视频流才能在浏览器播放&#xff09; 解决&#xff1a; 软件编码&#xff1a;需要源码编译opencv 1.环境准备 pip uninstall opencv-python sudo apt install build-essential cmake git python…

解决http的web服务中与https服务交互的问题

问题背景&#xff1a; 需要在一个http的web服务中直接跟另一个https服务交互&#xff0c;不经过自身后端。 又来到了熟悉的跨域访问问题。 解决逻辑就是使用nginx转发&#xff0c;涉及到的文件也就是nginx.conf文件&#xff0c;前面解决minio链接时已经有经验了&#xff0c;但…

网站访问信息追踪系统在安全与性能优化中的关键作用——网络安全—仙盟创梦IDE

<?php // 收集访问信息 $visitorInfo未来之窗 [timestamp > date(Y-m-d H:i:s),ip > $_SERVER[REMOTE_ADDR] ?? unknown,page > $_SERVER[REQUEST_URI] ?? unknown,method > $_SERVER[REQUEST_METHOD] ?? unknown,user_agent > $_SERVER[HTTP_USER_A…

Oracle 时间处理函数和操作符笔记

前言 写sql时经常用到时间处理函数&#xff0c;我整理了一份Oracle的常用sql笔记,供大家参考。 如果对你有帮助&#xff0c;请点赞支持~ 多谢&#x1f64f; 笔记 -- 1. 获取当前日期和时间 -- SYSDATE, SYSTIMESTAMP, CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP SELE…

TDengine时序数据库 详解

1. TDengine 简介 TDengine 是一款 高性能、分布式、支持 SQL 的时序数据库&#xff08;Time-Series Database, TSDB&#xff09;&#xff0c;专为 物联网&#xff08;IoT&#xff09;、工业互联网、金融监控、日志分析 等场景设计。其核心特点包括&#xff1a; 超高性能&…

【IDEA】idea怎么修改注册的用户名称?

文章目录[toc]问题**方法 1&#xff1a;通过 JetBrains 账户网站修改****方法 2&#xff1a;通过 IDEA 内跳转修改&#xff08;快捷方式&#xff09;****注意事项****补充&#xff1a;修改 IDEA 内的项目级用户名**如何退出IDEA用户登录&#xff1f;问题 在 IntelliJ IDEA 中修…

AR眼镜重塑外科手术导航:精准“透视”新突破

在现代医学领域&#xff0c;增强现实&#xff08;AR www.teamhelper.cn &#xff09;技术正以前所未有的方式改变外科手术导航的面貌。通过为医生提供实时的三维可视化、精准的空间定位和智能交互功能&#xff0c;AR眼镜正在成为手术室中的重要工具。本文将系统介绍AR眼镜在手术…

服务端对接 HTTP 接口传输图片 采用base64还是 multipart/form-data

在服务端对接HTTP接口传输图片时&#xff0c;选择 multipart/form-data 还是 Base64 编码&#xff0c;需要根据具体场景权衡。以下是详细对比和建议&#xff1a;1. multipart/form-data 优点 更适合大文件传输&#xff1a; 直接以二进制流传输图片&#xff0c;无需编码/解码&am…

如何在 Windows 上安装 MongoDB 及常见问题

MongoDB 是一款 NoSQL 数据库&#xff0c;在数据管理和存储方面以其无与伦比的强大功能和多功能性而脱颖而出。该平台凭借其灵活性、可扩展性和高性能保持着领先优势&#xff0c;赢得了众多企业的信赖。在这方面&#xff0c;MongoDB 以及其在 Windows 操作系统中的表现&#xf…