0

0

Spring 中 @PostConstruct 执行两次的原因及解决方案

DDD

DDD

发布时间:2025-07-19 17:34:10

|

786人浏览过

|

来源于php中文网

原创

spring 中 @postconstruct 执行两次的原因及解决方案

本文旨在解释 Spring 应用中 @PostConstruct 注解修饰的方法被执行两次的原因,并提供相应的解决方案。通常,这种情况是由于存在多个 Spring 上下文导致 Bean 被重复创建和初始化。理解 Spring 上下文的创建和管理是解决此问题的关键。

问题分析

在 Spring 应用中,@PostConstruct 注解用于标记在 Bean 初始化完成后需要执行的方法。Spring 容器负责管理 Bean 的生命周期,并在 Bean 实例化并完成依赖注入后调用被 @PostConstruct 注解的方法。

当 @PostConstruct 方法被执行多次时,通常是因为存在多个 Spring 容器实例。每个容器都会管理自己的 Bean,并按照生命周期管理 Bean 的初始化过程,因此会导致 @PostConstruct 方法被多次调用。

在您提供的代码示例中,问题在于 TextFilter 类中手动创建了一个新的 AnnotationConfigApplicationContext 实例:

public class TextFilter {
    private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    private MyCache cache;

    public TextFilter() {
        this.context.scan("com.sensitive_words.utils");
        this.context.refresh();
        this.cache = this.context.getBean(MyCache.class);
    }

    public String filter(String originalText) {
        return this.cache.get().filter(originalText);
    }
}

TextFilter 的构造函数创建并刷新了一个新的 Spring 容器。这意味着除了主应用程序上下文(由 SensitiveWordsApplication 创建)之外,还存在第二个容器。MyCache Bean 在这两个容器中都会被创建,因此 @PostConstruct 方法会被调用两次。

解决方案

解决此问题的关键在于避免创建不必要的 Spring 容器。应该只使用主应用程序上下文来管理 Bean。

以下是几种可行的解决方案:

1. 将 TextFilter 也声明为一个 Bean,并使用依赖注入:

BizPower CRM客户管理系统
BizPower CRM客户管理系统

通过使用BizPower CRM解决方案,您的员工、生产过程及信息能够与客户保持着平稳、无间断的联络,并且能够通过以客户为焦点、创新的产品和服务;以客户为中心,更高层次的生产过程;持久有益的客户关系这三个方面创造有价值客户的领导关系。选择Bizpower CRM的原因1、灵活的数据权限和功能权限BizPower CRM 系统通过引入了灵活的数据权限和功能权限,模仿现实中协同工作的实际情况。 实现企

下载

这是推荐的解决方案。让 Spring 管理 TextFilter 的生命周期,并将其依赖的 MyCache Bean 注入到 TextFilter 中。

@Component
public class TextFilter {

    private final MyCache cache;

    @Autowired
    public TextFilter(MyCache cache) {
        this.cache = cache;
    }

    public String filter(String originalText) {
        return this.cache.get().filter(originalText);
    }
}

确保 TextFilter 类被 Spring 容器扫描到。可以通过在包含 TextFilter 的包上添加 @ComponentScan 注解,或者使用 @Component 注解标记 TextFilter 类来实现。

2. 从主应用程序上下文中获取 MyCache Bean:

如果由于某些原因无法将 TextFilter 声明为 Bean,则可以从主应用程序上下文中获取 MyCache Bean。这需要访问主应用程序上下文,可以通过 ApplicationContextAware 接口来实现。但是,这种方法不太推荐,因为它使得 TextFilter 类与 Spring 容器耦合。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class TextFilter implements ApplicationContextAware {

    private MyCache cache;
    private ApplicationContext applicationContext;

    public TextFilter() {
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        this.cache = this.applicationContext.getBean(MyCache.class);
    }

    public String filter(String originalText) {
        return this.cache.get().filter(originalText);
    }
}

3. 移除手动创建的 ApplicationContext:

最简单的解决方案是直接删除 TextFilter 中手动创建的 AnnotationConfigApplicationContext,但这通常不可行,因为 TextFilter 可能需要依赖于Spring管理的Bean。

总结

@PostConstruct 方法被多次执行通常是由于存在多个 Spring 容器实例。通过避免手动创建 Spring 容器,并使用依赖注入来管理 Bean,可以有效地解决这个问题。推荐将所有需要使用 Spring 管理的 Bean 都交给 Spring 容器管理,避免手动创建容器。理解 Spring 上下文的生命周期和 Bean 的管理是解决此类问题的关键。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

103

2025.08.06

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1024

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

66

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

450

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.19

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

11

2026.01.19

微信聊天记录删除恢复导出教程汇总
微信聊天记录删除恢复导出教程汇总

本专题整合了微信聊天记录相关教程大全,阅读专题下面的文章了解更多详细内容。

79

2026.01.18

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

109

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

153

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
誉天教育RHCE视频教程
誉天教育RHCE视频教程

共9课时 | 1.4万人学习

尚观Linux RHCE视频教程(二)
尚观Linux RHCE视频教程(二)

共34课时 | 5.7万人学习

尚观RHCE视频教程(一)
尚观RHCE视频教程(一)

共28课时 | 4.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号