【踩坑记录】单测中@PostConstruct多次执行
问题复现:
单测中@PostConstruct修饰的方法被多次执行
原因:
@PostConstruct在Spring中常用于在构造函数后初始化对象,执行顺序如下:
构造方法->成员变量注入->PostConstruct方法
单测中由于某些原因,只希望初始化执行一次(当然一般是使用@BeforeClass或者@BeforeAll),不过我这里因为某些不可描述的原因,不希望使用静态方法进行初始化,因此想到了PostConstruct注解,单测执行后发现,初始化执行了多次,就是PostConstruct方法执行了多次。那首先怀疑,是不是所有单测方法运行的时候,都会构造一个单测对象呢?这样每次构造单测类对象后都会执行一次PostConstruct。debug验证了一下发现,跟猜想一样,Junit使用@RunWith(SpringRunner.class)执行时,项目启动时调用了一次构造,但是此时并没有调用PostConstruct方法,PostConstruct方法和Test都是在项目启动后执行的,然后每个单测方法执行都会依次执行 构造->PostConstruct方法->Test方法。
解决:
需要保证PostConstruct方法多次执行结果相同,即幂等,比如加个标识符或者判断一个待初始化的值是否已被初始化,另外需要注意,这个待初始化的值需要是static的,保证每次执行PostConstruct方法时拿到的都是同一个变量
其实写完之后感觉,如果这样用的话,不是跟@Before效果一样了。(补充:后来测了一下确实一样)
最后还是推荐使用@BeforeClass,如果你用@BeforeClass修饰的方法不是静态的,或者不好改成静态的,多半是代码写的有问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端