Spring @PostConstruct 、@Autowired和Construct 顺序

本文详细解析了@PostConstruct注解的用途与规则,强调其在依赖注入完成后执行初始化的作用,通过示例代码展示了构造方法、@Autowired与@PostConstruct的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  今天修bug的时候发现了@PostConstruct 注解,之前一直没注意到,今天正好学习了下,就来总结一波。

  @PostConstruct 

PostConstruct注释用于在完成依赖项注入以执行任何初始化之后需要执行的方法。必须在类投入使用之前调用此方法。
所有支持依赖注入的类都必须支持此注释。即使类没有请求注入任何资源,也必须调用使用PostConstruct注释的方法。
只有一个方法可以使用此批注进行批注。
应用PostConstruct注释的方法必须满足以下所有条件:除了拦截器之外,方法绝不能有任何参数,在这种情况下它采用Interceptor规范定义的InvocationContext对象。
在拦截器类上定义的方法必须具有以下签名之一:
void <METHOD>(InvocationContext)Object <METHOD>(InvocationContext)抛出异常注意:
PostConstruct拦截器方法不能抛出应用程序异常,但可以声明它抛出检查异常,包括java.lang.Exception,
如果相同的拦截器方法除了生命周期事件之外插入业务或超时方法。
如果PostConstruct拦截器方法返回一个值,容器将忽略它。
在非拦截器类上定义的方法必须具有以下签名:void <METHOD>()应用PostConstruct的方法可以是public,protectedpackage private或private。
除应用程序客户端外,该方法绝不能是静态的。
该方法可能是最终的。如果该方法抛出一个未经检查的异常,那么该类绝不能投入使用,除非EJB可以处理异常甚至从它们恢复的EJB

  然后就会思考问题,这个注释是修饰初始化之后需要执行的方法,那么它和@Autowired、构造函数的执行顺序是什么呢?(当然注释中已经说明了PostConstruct注释用于在完成依赖项注入之后)

  

@Service
public class BeanA {

    @Autowired
    private BeanB beanB;

    public BeanA() {
        System.out.println("这是Bean A 的构造方法");
    }


    @PostConstruct
    private void init() {
        System.out.println("这是BeanA的 init 方法");
        beanB.testB();
    }
}
@Service
public class BeanB {

    @PostConstruct
    private void init() {
        System.out.println("这是BeanB 的init 方法");
    }

    public BeanB() {
        System.out.println("这是Bean B的 构造方法");
    }

    void testB() {
        System.out.println("这是Bean B 的 testB 方法");
    }
}

启动后输出:

这是Bean A 的构造方法
这是Bean B的 构造方法
这是BeanB 的init 方法
这是BeanA的 init 方法
这是Bean B 的 testB 方法

所以得到结论: 构造方法 > @Autowired > @PostConstruct

转载于:https://www.cnblogs.com/haoming1100/articles/9960171.html

Spring 容器中,`@Autowired` `@PostConstruct` 注解的执行顺序是固定的,并且遵循依赖注入初始化阶段的规范流程。 当一个 Bean 被创建时,Spring 会先完成构造方法的调用,然后进行依赖注入。也就是说,`@Autowired` 注解所标注的字段、方法或构造函数会在 Bean 的构造方法执行完毕之后被处理[^1]。这意味着如果某个类中存在通过 `@Autowired` 注入的依赖,这些依赖将在构造函数执行完成之后被注入到该 Bean 中。 随后,在所有依赖注入完成之后,Spring 会执行使用 `@PostConstruct` 注解的方法。这个注解通常用于标记那些需要在依赖注入完成后执行的初始化逻辑。例如,可以用来建立数据库连接、加载缓存数据等操作。因此,`@PostConstruct` 方法是在依赖注入完成之后才被调用的[^2]。 以下是一个简单的代码示例,展示了这两个注解的执行顺序: ```java @Component public class ExampleBean { private Dependency dependency; @Autowired public void setDependency(Dependency dependency) { this.dependency = dependency; System.out.println("Dependency injected"); } @PostConstruct public void init() { System.out.println("Initialization logic here"); } public ExampleBean() { System.out.println("Constructor executed"); } } ``` 在这个例子中,输出顺序将是: 1. 构造函数输出“Constructor executed”。 2. 依赖注入方法输出“Dependency injected”。 3. 初始化方法输出“Initialization logic here”。 需要注意的是,`@PostConstruct` 是 JSR-250 标准的一部分,它并不局限于 Spring 框架,但 Spring 支持这一标准。此外,为了确保这些注解能够正常工作,必须启用注解驱动的配置,这通常是通过 `<context:annotation-config/>` 或者 `@AnnotationConfigApplicationContext` 来实现的[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值