背景
在实际开发中,我们经常会需要进行一些初始化操作,比如进行一些预加载和赋值之类的。在代码中,常见的有通过静态代码块、非静态代码块,@PostConstruct来实现初始化。那么既然他们都可以实现初始化操作,那么他们有什么区别呢?
使用方式
- 静态代码块:是用
static
关键字定义的一段代码块,用于初始化类的静态成员 - 非静态代码块:是没有
static
关键字的代码块,用于初始化实例成员 @PostConstruct:
是一个用于标注方法的注解,该方法会在依赖注入完成后被自动调用
执行时机
- 静态代码块:在类加载时执行,只会执行一次,适用于类级别的初始化
- 非静态代码块:在每次创建类的实例时执行,即每次调用构造函数时都会执行,执行顺序在构造方法之前
@PostConstruct:
当 Spring 容器初始化 bean 时,在所有的依赖注入完成后执行该方法。适用于 Spring 管理的 bean
作用范围
- 静态代码块:只能访问静态变量和静态方法,不能直接访问实例变量和实例方法。因为它们在类加载时执行,而实例变量和方法需要在对象创建时才存在
- 非静态代码块:可以访问实例变量和实例方法,也可以访问静态变量和静态方法。不能访问在构造函数中通过参数注入的依赖,因为非静态代码块在构造函数执行之前执行
@PostConstruct:
可以访问实例变量和实例方法,也可以访问静态变量和静态方法。可以访问Bean的属性,因为它在依赖注入完成之后执行
应用场景
- 静态代码块:只需要执行一次的初始化操作,通常用于设置静态变量的默认值、加载静态资源等。
- 非静态代码块:适用于那些需要在每次实例化时执行的初始化操作,通常用于设置实例变量的默认值,或者执行一些实例级别的初始化逻辑。
@PostConstruct:
通常用于执行一些需要依赖注入完成后的初始化逻辑,如初始化复杂对象、执行数据库连接等。
总结对比
特性 | 静态代码块 | 非静态代码块 | @PostConstruct 注解 |
---|---|---|---|
定义位置 | 类级别 | 实例级别 | 类中的方法 |
执行时机 | 类加载时执行 | 每次实例化时执行 | 依赖注入后执行 |
调用次数 | 只调用一次 | 每次创建对象时调用 | 每个 bean 创建时调用,单例只调用一次 |
访问权限 | 只能访问静态成员 | 可以访问实例和静态成员 | 可以访问实例、静态成员和依赖注入的Bean |
适用场景 | 类级别初始化 | 实例级别初始化 | Spring 容器管理的 bean 初始化 |
静态代码块适用于类级别的静态初始化,非静态代码块适用于每个对象的初始化,而 @PostConstruct
则适合在 Spring 中进行依赖注入后的初始化。