Spring 框架中 @PostConstruct 注解详解

Posted 快乐的小码农2号选手

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 框架中 @PostConstruct 注解详解相关的知识,希望对你有一定的参考价值。

在Spring项目经常遇到@PostConstruct注解,首先介绍一下它的用途: 被注解的方法,在对象加载完依赖注入后执行。此注解是在Java EE5规范中加入的,在Servlet生命周期中有一定作用,它通常都是一些初始化的操作,但初始化可能依赖于注入的其他组件,所以要等依赖全部加载完再执行。与之对应的还有@PreDestroy,在对象消亡之前执行,原理差不多。

一、@PostConstruct认识

此注解是在Java
EE5规范中加入的,在Servlet生命周期中有一定作用,它通常都是一些初始化的操作,但初始化可能依赖于注入的其他组件,所以要等依赖全部加载完再执行

官方注释

构造后注释用于一个方法,该方法需要在依赖项注入完成后执行,以执行任何初始化。必须在类投入服务之前调用此方法。所有支持依赖项注入的类都必须支持此注释。即使类不请求注入任何资源,也必须调用用PostConstruct注释的方法。给定类中只有一个方法可以使用此注释进行注释。应用构造后注释的方法必须满足以下所有条件:
该方法不能有任何参数,但在拦截器的情况下除外,在拦截器的情况下,它接受拦截器规范定义的InvocationContext对象。
在拦截器类或拦截器类的超类上定义的方法必须具有以下签名之一: void (调用上下文) 对象 方法> (调用上下文)引发异常
注意:构造后拦截器方法不得引发应用程序异常,但如果同一拦截器方法在生命周期事件之外插入业务或超时方法,则可以声明该方法引发已检查的异常,包括java.lang.Exception。如果PostConstruct拦截器方法返回值,则容器将忽略该值。
在非侦听器类上定义的方法必须具有以下签名: void 方法> ()
应用PostConstruct注释的方法可以是public、protected、package private或private。
除应用程序客户端外,该方法不能是静态的。 方法不应该是最终的。 如果该方法抛出未经检查的异常,则该类不得投入服务,除非该异常由拦截器处理。

  1. 要在依赖加载后,对象使用前执行,而且只执行一次,原因在上面已经说了。
  2. 所有支持依赖注入的类都要支持此方法。

此外,我们可以看到这个注解是在javax.annotation包下的,也就是java拓展包定义的注解,并不是spring定义的,而spring是支持依赖注入的,因此spring必须要自己来实现@PostConstruct的功能。

二、@PostConstruct注释规则

  1. 除了拦截器这个特殊情况以外,其他情况都不允许有参数,否则spring框架会报IllegalStateException;而且返回值要是void,但实际也可以有返回值,至少不会报错,只会忽略

  2. 方法随便你用什么权限来修饰,public、protected、private都可以,反正功能是由反射来实现

  3. 方法不可以是static的,但可以是final的

所以,综上所述,在spring项目中,在一个bean的初始化过程中,方法执行先后顺序为

Constructor > @Autowired > @PostConstruct

先执行完构造方法,再注入依赖,最后执行初始化操作,所以这个注解就避免了一些需要在构造方法里使用依赖组件的尴尬。

三、总结

总之就是用来执行一些初始化操作,被修饰的方法权限可以是任何的类型,但是被修饰的方法返回值必须是void,执行顺序是在我们的类构造器,自动注入对象注入后,最后执行我们的方法。
Constructor > @Autowired > @PostConstruct
eg:

  @PostConstruct
    private void init() 
        // 设置内部接口的实现类
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    

以上是关于Spring 框架中 @PostConstruct 注解详解的主要内容,如果未能解决你的问题,请参考以下文章

@PostConstruct

@PostConstruct注解介绍

SpringBoot @PostConstruct的用法

Mockito + Spring + @PostConstruct,mock初始化错误,为啥会调用@PostConstruct?

如何在 Web 容器中使用 Spring 批处理获取 @Postconstruct?

8 -- 深入使用Spring -- 2...4 使用@PostConstruct和@PreDestroy定制生命周期行为