You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《Spring实战》学习:jdbcTemplate bean创建偶现找不到dataSource错误

问题根源

设置激活Profile的时序错误是导致偶现启动失败的核心原因:
你重写onStartup方法时先执行了super.onStartup(servletContext),该方法会直接触发Spring上下文的完整初始化流程,包括Bean定义的解析、Profile匹配、Bean实例化。而你是在super.onStartup执行完成后才向ServletContext设置spring.profiles.active参数,此时Spring已经完成了Profile匹配逻辑,两个标注了@Profile的dataSource Bean都没有被注册到容器中,因此后续创建jdbcTemplate时会抛出找不到dataSource的异常。
问题偶现是因为Servlet容器的参数读取逻辑存在时序波动,极少数情况下Spring上下文初始化时能读取到提前写入的参数,但该逻辑并不稳定。
额外说明:你添加的@DependsOn注解没有实际作用,Spring会自动根据方法参数的依赖关系控制Bean创建顺序,jdbcTemplate的入参要求注入DataSource,本来就会等待DataSource创建完成后再实例化。

解决方案

方案1:调整onStartup执行顺序

将参数设置逻辑放到super.onStartup之前,保证Spring初始化前能读取到激活的Profile:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    // 先设置Profile参数
    servletContext.setInitParameter("spring.profiles.active", "prod");
    // 再执行上下文初始化
    super.onStartup(servletContext);
}

方案2:重写Initializer的Profile指定方法(更稳妥)

直接重写AbstractAnnotationConfigDispatcherServletInitializer提供的Profile配置方法,优先级高于Servlet上下文参数,不会出现时序问题:

// 指定DispatcherServlet对应Web上下文的激活Profile
@Override
protected String[] getServletProfiles() {
    return new String[]{"prod"};
}
// 如果你的dataSource配置在根上下文,还可以重写根上下文的Profile配置
@Override
protected String[] getRootProfiles() {
    return new String[]{"prod"};
}

内容的提问来源于stack exchange,提问作者LIL PIGGY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 01:39:02