本文主要是介绍Spring Bean初始化及@PostConstruc执行顺序示例详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的...
1. Bean初始化执行顺序
构造函数 - 首先调用Bean的构造函数
依赖注入 - 完成所有依赖项的注入(@Autowired等)
@PostConstruct方法 - 执行带有
@PostConstruct
注解的方法InitializingBean的afterPropertiesSet() - 如果Bean实现了
InitializingBeanhttp://www.chinasem.cn
接口自定义init方法 - 执行通过
@Bean(initMethod="...")
或XML配置中init-method
指定的方法
@Component public class ExampleBean implements InitializingBean { public ExampleBean() { System.out.println("1. 构造函数"); } @Autowired public void setDependency(SomeDependency dep) { js System.out.println("2. 依赖注入"); } @PostConstruct public void postConstruct() { System.out.println("3. @PostksydNXmRConstruct方法"); } @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
关键字调用构造器之前)。规则:所有成员变量先被赋予默认值(
int
→0
,boolean
→false
,引用类型→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(显式赋值和初始化块先执行,构造器China编程最后执行)。
到此这篇关于Spring Bean初始化及@PostConstruc执行顺序的文章就介绍到这了,更多相关Spring Bean初始化内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Spring Bean初始化及@PostConstruc执行顺序示例详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!