Spring Boot WAR包部署到Tomcat后无法读取application.properties文件
兄弟我太懂你这种折腾的憋屈感了!之前硬编码JNDI能顺顺当当跑起来,换成配置文件就掉坑里,确实摸不着头脑。我结合自己踩过的坑,给你梳理几个最可能的原因和解决办法,你挨个排查下:
1. 先确认配置文件有没有被打包进WAR里
这是最容易忽略的点!Spring Boot WAR部署时,默认会读取WEB-INF/classes目录下的配置文件。你可以手动解压生成的WAR包,看看这个路径下有没有application.properties,并且内容是你修改后的正确配置。
如果没有,那就是打包环节出问题了。比如用Maven的话,检查pom.xml里的<resources>配置,确保把src/main/resources下的文件都拷贝到了classes目录中,典型配置如下:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
2. 自定义配置类和自动配置冲突了
你之前写了DataSourceConfig硬编码JNDI,现在换成配置文件后,有没有把这个类删掉或者调整?如果这个类还存在,Spring会优先使用你自定义的DataSource Bean,而忽略application.properties里的配置,这就等于白改了!
解决办法有两个:
- 直接删掉
DataSourceConfig类,Spring Boot的自动配置会读取application.properties里的JNDI配置,帮你创建DataSource。 - 如果你想保留这个类,给它加上
@ConditionalOnMissingBean注解,这样只有当自动配置没生效时才会用你的自定义Bean:
@Configuration public class DataSourceConfig { @Bean @ConditionalOnMissingBean public DataSource dataSource() { return (DataSource) new JndiTemplate().lookup("java:/comp/env/jdbc/myJndiLocal"); } }
3. 配置文件里的JNDI属性写错了
用Spring Boot自动配置的话,JNDI的配置项写法是固定的,别写错了!正确的配置应该是:
spring.datasource.jndi-name=java:/comp/env/jdbc/myJndiLocal
注意是spring.datasource.jndi-name,不是自己随便起的属性名,否则Spring没法识别。
4. 启动类没继承SpringBootServletInitializer
WAR包部署到Tomcat时,启动类必须继承SpringBootServletInitializer,否则Spring Boot没法正确初始化上下文,自然也读不到配置文件。你的启动类应该是这样的:
@SpringBootApplication public class YourApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(YourApplication.class); } public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
5. 排除编码或类加载顺序问题
- 如果配置文件里有中文或特殊字符,确保它是UTF-8编码,Maven打包时也指定编码:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties>
- 另外,避免把配置文件放到Tomcat的共享类库目录(比如
lib或conf),否则Tomcat的类加载器可能读取到全局配置,而不是你应用自己的application.properties。
你按照这个顺序排查下来,大概率能解决问题!
备注:内容来源于stack exchange,提问作者Curtis Snowden

