spring的多个@PostConstruct之间执行顺序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring的多个@PostConstruct之间执行顺序相关的知识,希望对你有一定的参考价值。

多个@PostConstruct之间执行顺序

参考技术A 自己多弄几个@PostConstruct,在每个里面打印下日志,试试就知道了呗~

@PostConstruct 注解和spring生命周期

【中文标题】@PostConstruct 注解和spring生命周期【英文标题】:@PostConstruct annotation and spring lifecycle 【发布时间】:2017-11-24 15:43:52 【问题描述】:

我是Spring新手,我想知道:

我有一个用@Component (spring) 注释的java 类,在里面我有一个用@PostConstruct 注释的方法。然后该类被另一个类中的@Autowired 注释字段引用。我可以假设只有在调用@PostConstruct 之后才注入该类吗?

@Component
class AuthenticationMetrics 

    private static final MetricRegistry metrics = new MetricRegistry();

    final Counter requestsTotal;

    final Meter guestLogins;

    final Meter kfUserLogins;

    final Timer guestLoginResponseTime;

    final Timer kfLoginResponseTime;

    @PostConstruct
    public void populateMetricsRegistry() 
        metrics.counter("authentication.requests.totals");
    

【问题讨论】:

是的,你可以假设它...... Spring首先创建bean,然后检查最终的@PostConstruct注解,最后注入bean。无论如何,我看到您在 populateMetricsRegistry 方法中使用了非弹簧对象。在这种情况下,对于这个对象(指标对象),管理正确的生命周期是您自己的责任 我对另一个类感到困惑。您的 AuthenticationMetrics 类将被实例化,其字段将被注入(本示例中没有),然后将调用 @PostConstruct。如果你在某处注入AuthenticationMetrics,它将在somewhere@PostConstrtuct被调用之前被注入。 【参考方案1】:

如果您要问的是在调用该 bean 中的 @PostConstruct 之后发生给定类的注入,那么答案是肯定的 - @PostConstruct 在 bean 被视为“可注入”之前执行

如果您询问是否在所有注入完成后(在同一个 bean 上)执行给定 bean 上的 @PostConstruct - 那么是 - 在将注入提交给给定 bean 后执行 @PostConstruct。这就是它存在的原因。通常您可以将@PostConstruct 操作放入构造函数中。但是,当创建新对象(调用构造函数)时,尚未执行注入 - 因此任何依赖于注入对象的初始化都会因 NPE 而失败。这就是为什么你需要@PostConstruct

【讨论】:

嗨,是的,我想知道 @PostConstruct 是否在 bean 被视为“可注入”之前执行,这是我想知道的。谢谢! 您可以删除此部分:“如果您询问 @PostConstruct 执行是否意味着 bean 被注入某处 - 那么没有。”我会接受答案。 那么这是否意味着在进行构造函数注入时,@PostConstruct 绝对没有用例?【参考方案2】:

@PostConstruct@Resource@PreDestroy 等注解的处理是通过 BeanPostProcessor 完成的,在本例中为 CommonAnnotationBeanPostProcessor。您可以在 Spring 的下图中看到,这些 BPP 是在 after 依赖注入但 before Bean Ready For Use 处理的(这意味着与可注入一样多)。

【讨论】:

@PostConstruct 之后的下一个生命周期步骤是什么?我想通过自定义interceptor将用户详细信息从principal附加到request header..请帮助 @Kalanka 也许会问一个新问题?并在此处链接回它。;。 :)【参考方案3】:

是的。 Bean 创建工作流程是:

    构造函数调用 @Autowired 字段 @Autowired二传手 BeanPostProcessor 的postProcessBeforeInitialization(),即由CommonAnnotationBeanPostProcessor 调用的@PostConstruct InitializingBean.afterPropertiesSet() BeanPostProcessor 的postProcessAfterInitialization() Bean 已准备就绪,可以注入其他 Bean

【讨论】:

您在第 5 步和第 6 步之间缺少init() 或其他自定义初始化方法

以上是关于spring的多个@PostConstruct之间执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

@PostConstruct

Spring学习-----Spring @PostConstruct和@PreDestroy实例

Spring - @PostConstruct 源码解析

Spring - @PostConstruct 源码解析

Spring@PostConstruct和@PreDestroy注解详解

使用@Cacheable 的Spring 缓存在启动@PostConstruct 时不起作用