SpringBoot中懒加载对@PostConstruct的影响
文章目录
Springboot 中不同方式注入Bean先后顺序
在
Spring Boot
中,构造函数、Setter
方法、@Autowired
、@PostConstruct
等方式初始化bean
的执行先后顺序如下:
构造函数执行
- 当
Spring
创建一个bean
实例时,首先会调用构造函数来初始化对象。 - 如果构造函数中有参数,且这些参数对应的
bean
也需要被创建,那么Spring
会先创建这些依赖的bean
,再调用当前bean
的构造函数。
@Autowired
注入(如果在构造函数中)
- 如果构造函数上标注了
@Autowired
,那么在构造函数执行过程中,Spring
会自动注入依赖的bean
。 - 这通常发生在构造函数参数被解析和注入的时候。
Setter 方法执行(如果有依赖注入)
- 在构造函数执行之后,如果有通过
setter
方法进行依赖注入的情况,Spring 会调用相应的 setter 方法来注入依赖的bean
。 - 如果
setter
方法上标注了@Autowired
,那么在调用setter
方法时也会进行自动注入。
@PostConstruct
方法执行
- 一旦
bean
的实例化通过构造函数完成,并且依赖注入(无论是通过构造函数还是setter
方法)也完成后,Spring
会查找标注有@PostConstruct
注解的方法,并执行这些方法。 - 这个阶段通常用于执行一些额外的初始化逻辑,例如配置资源、初始化连接等。
代码实例
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private Dependency dependency;
@Autowired
public MyBean(Dependency dependency) {
this.dependency = dependency;
System.out.println("Constructor with @Autowired executed.");
}
@Autowired
public void setDependency(Dependency dependency) {
this.dependency = dependency;
System.out.println("Setter method with @Autowired executed.");
}
@PostConstruct
public void init() {
System.out.println("@PostConstruct method executed.");
}
}
- 在这个例子中,执行顺序会是先调用带有
@Autowired
的构造函数,然后如果有setter
方法且标注了@Autowired
,会执行setter
方法,最后执行标注有@PostConstruct
注解的方法。 - 这个顺序是一般情况下的执行顺序,但在复杂的应用场景中,可能会受到其他因素的影响,例如循环依赖、懒加载等。在设计和开发应用时,应该充分考虑这些因素,以确保
bean
的初始化过程符合预期。
懒加载对 @PostConstruct
的影响
- 当一个
bean
被标记为懒加载时,它的实例化会被延迟到首次被实际使用的时候。 @PostConstruct
注解的方法在bean
实例化完成并且属性注入完成后被调用。如果bean
是懒加载的,那么@PostConstruct
方法也会在这个bean
被首次使用时才执行,而不是在Spring
容器启动时执行。- 对于懒加载的
bean
,只有在实际被使用时,才会经历创建、属性注入和@PostConstruct
方法执行的过程
@Component
public class NonLazyBean {
@PostConstruct
public void initNonLazy() {
System.out.println("NonLazyBean @PostConstruct executed.");
}
}
@Component
@Lazy
public class LazyBean {
@PostConstruct
public void initLazy() {
System.out.println("LazyBean @PostConstruct executed.");
}
}
在上面的代码中,如果有其他非懒加载的 bean
依赖于 NonLazyBean
,那么在 Spring
容器启动时,NonLazyBean
的 @PostConstruct
方法会先执行。而 LazyBean
的 @PostConstruct
方法只有在 LazyBean
被实际使用时才会执行。
- 如果一个懒加载的
bean
依赖于一个非懒加载的bean
,并且在非懒加载bean
的@PostConstruct
方法中尝试访问懒加载的bean
,可能会导致空指针异常,因为此时懒加载的bean
还未被实例化。
解决方法
- 可以在判断获取到的
bean
是否为空,为空从容器中重新获取 - 调整代码逻辑不使用
@PostConstruct
注解。