下面我将详细介绍几种最主流和推荐的方法,从传统的 Servlet API 到现代的 Spring/Spring Boot 框架。

传统 Servlet 方式 (不依赖框架)
在 Java Web 应用的早期,我们主要使用 Servlet API 来读取配置文件,Servlet 规范定义了两个主要的配置文件位置:
web.xml: 部署描述符,可以配置初始化参数。/WEB-INF/classes目录: 存放应用的资源文件,如.properties或.xml文件,这个目录下的文件会被 ClassLoader 自动加载。
读取 web.xml 中的初始化参数
这种方式通常用于配置整个 Web 应用的全局参数。
-
在
web.xml中配置参数<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 定义上下文初始化参数 --> <context-param> <param-name>systemConfigPath</param-name> <param-value>/WEB-INF/config/system.properties</param-value> </context-param> <!-- 定义 Servlet 初始化参数 --> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> <init-param> <param-name>dbUser</param-name> <param-value>admin</param-value> </init-param> </servlet> </web-app> -
在 Java 代码中读取
(图片来源网络,侵删)-
在 Servlet 中读取
init-param:import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; public class MyServlet extends HttpServlet { @Override public void init() throws ServletException { // 只能读取当前 Servlet 的 init-param String dbUser = getInitParameter("dbUser"); System.out.println("Servlet init-param dbUser: " + dbUser); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // ... } } -
在任何地方读取
context-param:import javax.servlet.ServletContext; // 在 Servlet 中获取 ServletContext context = getServletContext(); String configPath = context.getInitParameter("systemConfigPath"); System.out.println("Context-param systemConfigPath: " + configPath); // 也可以通过 JNDI 在其他类中获取 ServletContext // context = (ServletContext) new InitialContext().lookup("java:comp/env");
-
读取 src/main/resources 下的属性文件
这是最传统的方式,通过 ClassLoader 来读取。
假设你的项目结构如下:

src/
└── main/
├── java/
│ └── com/
│ └── example/
│ └── MyServlet.java
└── resources/
└── database.properties
在 Spring 框架提供了更强大、更灵活的方式来管理配置。 这是 Spring 中读取外部属性文件最常用和最优雅的方式。 创建属性文件
在 配置类
创建一个配置类,并使用 在应用中使用 Spring Boot 极大地简化了配置管理,它遵循“约定优于配置”的原则。 Spring Boot 会自动在 在任意 Spring Bean(如 这是 Spring Boot 中最推荐的方式,用于管理一组相关的配置,它能将配置文件中的属性绑定到一个 Java 对象,类型安全且代码清晰。 创建属性文件
创建配置属性类
使用 在应用中使用
Spring Boot 会自动创建并注册这个 Bean,你只需要 Spring Boot 支持不同环境的配置文件,非常实用。 在 然后在 最终建议:database.properties
db.url=jdbc:mysql://localhost:3306/mydb
db.username=root
db.password=secret
MyServlet 中读取:import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取 ClassLoader
ClassLoader classLoader = getClass().getClassLoader();
// 2. 通过 ClassLoader 获取输入流
// 注意:路径是相对于 resources 目录的,不要以 "/" 开头
InputStream inputStream = classLoader.getResourceAsStream("database.properties");
if (inputStream != null) {
Properties props = new Properties();
props.load(inputStream);
String url = props.getProperty("db.url");
String username = props.getProperty("db.username");
String password = props.getProperty("db.password");
System.out.println("DB URL: " + url);
System.out.println("DB User: " + username);
inputStream.close();
} else {
System.err.println("Sorry, unable to find database.properties");
}
}
}
Spring Framework 方式
使用
@PropertySource 和 @Value (推荐)
src/main/resources 下创建 app.properties:app.name=My Spring Application
app.version=1.0.0
@PropertySource 来指定属性文件的位置。import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:app.properties") // classpath: 表示从 resources 目录加载
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
// 可以提供一个 getter 方法来在其他地方使用
public String getAppName() {
return appName;
}
public String getAppVersion() {
return appVersion;
}
// 打印出来测试
public void print() {
System.out.println("App Name from @PropertySource: " + appName);
System.out.println("App Version from @PropertySource: " + appVersion);
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private AppConfig appConfig;
@GetMapping("/config")
public String getConfig() {
appConfig.print(); // 调用方法打印
return "App Name: " + appConfig.getAppName() + ", Version: " + appConfig.getAppVersion();
}
}
使用
Environment 对象Environment 是 Spring 的核心接口,可以统一访问所有属性源,包括系统属性、环境变量、以及通过 @PropertySource 加载的文件。import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EnvironmentController {
@Autowired
private Environment env;
@GetMapping("/env-config")
public String getEnvConfig() {
// 通过 getProperty 方法获取属性,可以设置默认值
String appName = env.getProperty("app.name", "Default App Name");
String dbUrl = env.getProperty("db.url"); // 如果没有该属性,返回 null
System.out.println("App Name from Environment: " + appName);
System.out.println("DB URL from Environment: " + dbUrl);
return "App Name: " + appName;
}
}
Spring Boot 方式 (现代标准)
默认的
application.properties 或 application.ymlsrc/main/resources 目录下寻找 application.properties 或 application.yml 文件,并将其作为主配置文件。src/main/resources/application.properties:# 服务器端口
server.port=8081
# 自定义应用属性
myapp.name=My Boot App
myapp.feature.enabled=true
@Service, @RestController)中,可以直接使用 @Value 注入:import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BootConfigController {
@Value("${myapp.name}")
private String appName;
@Value("${myapp.feature.enabled}")
private boolean featureEnabled;
@GetMapping("/boot-config")
public String getBootConfig() {
return "App Name: " + appName + ", Feature Enabled: " + featureEnabled;
}
}
使用
@ConfigurationProperties (类型安全的配置)
src/main/resources/application.properties:# 数据库配置
datasource.url=jdbc:mysql://localhost:3306/mydb
datasource.username=root
datasource.password=secret
datasource.pool-size=10
@ConfigurationProperties 注解来绑定前缀。import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "datasource") // 绑定以 "datasource" 开头的属性
public class DataSourceProperties {
private String url;
private String username;
private String password;
private int poolSize;
// 必须提供标准的 getter 和 setter 方法
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public int getPoolSize() { return poolSize; }
public void setPoolSize(int poolSize) { this.poolSize = poolSize; }
@Override
public String toString() {
return "DataSourceProperties{" +
"url='" + url + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", poolSize=" + poolSize +
'}';
}
}
@Autowired 即可。import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BootPropertiesController {
@Autowired
private DataSourceProperties dataSourceProperties;
@GetMapping("/datasource-config")
public String getDatasourceConfig() {
return dataSourceProperties.toString();
}
}
多环境配置
application.properties: 通用配置application-dev.properties: 开发环境配置application-prod.properties: 生产环境配置application.properties 中通过 spring.profiles.active 来激活指定环境的配置:# 激活开发环境配置
spring.profiles.active=dev
application-dev.properties 中可以覆盖通用配置:# 开发环境使用不同的端口和数据库
server.port=8080
datasource.url=jdbc:mysql://dev-db:3306/mydb_dev
总结与对比
方法
适用场景
优点
缺点
Servlet API
无框架的纯 Java Web 项目
标准规范,所有 Servlet 容器都支持
代码冗余,功能单一,灵活性差
Spring
@PropertySourceSpring/Spring Boot 项目
灵活,可加载任意路径的文件,与 Spring 生态集成好
需要手动管理
Properties 对象,不如 @ConfigurationProperties 类型安全
Spring
EnvironmentSpring/Spring Boot 项目
统一访问所有属性源,功能强大
需要手动转换类型,不够直观
Spring Boot
@ValueSpring Boot 项目
简单,直接注入单个值到字段
适合少量、零散的配置,不适合管理一组相关配置
Spring Boot
@ConfigurationPropertiesSpring Boot 项目 (强烈推荐)
类型安全,代码清晰,适合管理一组相关配置
需要编写一个 POJO 类
web.xml 参数和 ClassLoader 读取 resources 下的文件。@PropertySource + @Value 或 @ConfigurationProperties。@ConfigurationProperties 来管理结构化配置,并用 application-{profile}.properties 来区分环境,对于少量、独立的配置,@Value 也是一个不错的选择。
