java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java加载Properties文件

从基础到实战全解析Java加载Properties文件的六种方式

作者:醉风塘

本文详细介绍了Java中Properties文件的六种加载方式,每种方式都有其适用场景、实现步骤、优缺点及最佳实践,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧

在Java开发中,Properties文件是最常用的配置文件格式之一,其以key=value的键值对结构存储配置信息(如数据库连接参数、接口地址、系统开关等),具有简洁易维护、解耦配置与代码的核心优势。不同场景下(如普通Java项目、Spring项目、Web应用、Java 9+模块化项目),Properties文件的加载方式存在差异。本文将详细拆解六种主流加载方式,包含适用场景、实现步骤、代码示例、优缺点及最佳实践,帮助开发者灵活应对各类配置加载需求。

一、核心前提:Properties文件基础

1. 文件格式与规范

# 数据库配置
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=123456
# 系统配置(中文需UTF-8编码)
system.name=测试系统

2. 核心API

Java通过java.util.Properties类操作Properties文件,核心方法:

二、六种加载方式详解

方式一:ClassLoader.getResourceAsStream()(类路径加载,最常用)

适用场景

核心原理

通过类加载器(ClassLoader)读取classpath下的资源文件,路径以classpath根目录为基准,无需写绝对路径,支持打包后(JAR/WAR)的资源加载。

实现步骤与代码示例

  1. 配置文件位置:src/main/resources/config.properties(Maven/Gradle项目标准目录)
  2. 加载代码(支持三种ClassLoader获取方式):
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class PropertiesLoader1 {
    public static void main(String[] args) {
        Properties props = new Properties();
        // 方式1:当前类的ClassLoader(推荐,避免线程上下文类加载器问题)
        try (InputStreamReader isr = new InputStreamReader(
                PropertiesLoader1.class.getClassLoader().getResourceAsStream("config.properties"),
                StandardCharsets.UTF_8)) { // 显式指定UTF-8编码,解决中文乱码
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }
        // 方式2:Thread上下文类加载器(适用于多线程/框架场景)
        /*try (InputStreamReader isr = new InputStreamReader(
                Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"),
                StandardCharsets.UTF_8)) {
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }*/
        // 方式3:系统类加载器(与方式1效果一致,不推荐)
        /*try (InputStreamReader isr = new InputStreamReader(
                ClassLoader.getSystemClassLoader().getResourceAsStream("config.properties"),
                StandardCharsets.UTF_8)) {
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }*/
        // 读取配置
        System.out.println("数据库URL:" + props.getProperty("db.url"));
        System.out.println("系统名称:" + props.getProperty("system.name")); // 中文正常显示
    }
}

路径规则

优缺点

方式二:FileInputStream(文件系统路径加载)

适用场景

核心原理

通过文件系统的绝对路径或相对路径,直接读取文件字节流,依赖操作系统的文件系统接口。

实现步骤与代码示例

  1. 配置文件位置:D:/config/config.properties(绝对路径)或./config.properties(项目根目录相对路径)
  2. 加载代码:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class PropertiesLoader2 {
    public static void main(String[] args) {
        Properties props = new Properties();
        String filePath;
        // 方式1:绝对路径(Windows/Dinux通用,Linux路径如"/opt/config/config.properties")
        filePath = "D:/config/config.properties";
        // 方式2:相对路径(基准目录为项目根目录,如IDEA中为项目文件夹)
        // filePath = "./config.properties";
        // 方式3:命令行参数传入路径(灵活适配不同环境)
        // if (args.length > 0) filePath = args[0];
        try (InputStreamReader isr = new InputStreamReader(
                new FileInputStream(filePath),
                StandardCharsets.UTF_8)) { // 指定UTF-8编码
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("加载配置文件失败,路径:" + filePath, e);
        }
        // 读取配置
        System.out.println("数据库用户名:" + props.getProperty("db.username"));
        System.out.println("数据库密码:" + props.getProperty("db.password"));
    }
}

路径规则

优缺点

方式三:Spring框架加载(@PropertySource + @Value)

适用场景

核心原理

Spring通过@PropertySource注解指定配置文件路径,由PropertySourcesPlaceholderConfigurer自动加载配置,结合@Value注解注入属性,支持classpath、文件系统路径、URL等多种资源。

实现步骤与代码示例

1. 普通Spring项目(XML配置)

<!-- applicationContext.xml -->
<context:component-scan base-package="com.example"/>
<context:property-placeholder 
    location="classpath:config.properties,file:D:/config/ext-config.properties" 
    file-encoding="UTF-8"/> <!-- 支持多文件、混合路径、指定编码 -->
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class SpringConfigLoader {
    // 注入配置属性,支持默认值
    @Value("${db.url}")
    private String dbUrl;
    @Value("${db.username}")
    private String dbUsername;
    @Value("${system.name:默认系统}") // 无该key时返回默认值
    private String systemName;
    // 测试方法
    public void printConfig() {
        System.out.println("Spring加载 - 数据库URL:" + dbUrl);
        System.out.println("Spring加载 - 系统名称:" + systemName);
    }
}

2. Spring Boot项目(注解驱动)

Spring Boot默认加载classpath:application.properties/application.yml,若需加载自定义文件,使用@PropertySource

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
// 加载classpath下的config.properties和外部文件
@Configuration
@PropertySource(value = {
        "classpath:config.properties",
        "file:D:/config/ext-config.properties"
}, encoding = "UTF-8") // 指定UTF-8编码(Spring 4.3+支持)
public class BootConfigLoader {
    @Value("${db.url}")
    private String dbUrl;
    @Value("${db.password}")
    private String dbPassword;
    @Value("${system.version:1.0.0}")
    private String systemVersion;
    // 提供getter方法供业务使用
    public String getDbUrl() {
        return dbUrl;
    }
    public String getDbPassword() {
        return dbPassword;
    }
}

3. Spring Boot 2.4+ 推荐方式(application.properties指定额外配置)

# application.properties
spring.config.import=classpath:config.properties,file:D:/config/ext-config.properties

路径规则

优缺点

方式四:Java 9+ Module资源加载(Module.getResourceAsStream())

适用场景

核心原理

Java 9引入模块系统(Module System)后,传统ClassLoader加载资源可能受模块权限限制,需通过Module接口的getResourceAsStream()方法加载模块内的资源,支持模块间的资源访问控制。

实现步骤与代码示例

  1. 模块化项目结构:
src/
├── main/
│   ├── java/
│   │   ├── com/
│   │   │   └── example/
│   │   │       └── ModuleConfigLoader.java
│   │   └── module-info.java
│   └── resources/
│       └── config.properties
  1. module-info.java配置(关键:开放资源访问权限):
// 模块名:com.example.config
module com.example.config {
    // 允许其他模块访问本模块的资源(可选,若仅内部使用可省略)
    opens com.example to java.base;
    // 导出包(若需外部模块使用加载类)
    exports com.example;
}
  1. 加载代码:
package com.example;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class ModuleConfigLoader {
    public static void main(String[] args) {
        Properties props = new Properties();
        // 方式1:通过当前类的Module加载(推荐)
        try (InputStreamReader isr = new InputStreamReader(
                ModuleConfigLoader.class.getModule().getResourceAsStream("config.properties"),
                StandardCharsets.UTF_8)) {
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("模块内加载配置文件失败", e);
        }
        // 方式2:通过模块名获取Module(需模块已加载)
        /*Module module = ModuleLayer.boot().findModule("com.example.config").orElseThrow();
        try (InputStreamReader isr = new InputStreamReader(
                module.getResourceAsStream("config.properties"),
                StandardCharsets.UTF_8)) {
            props.load(isr);
        } catch (IOException e) {
            throw new RuntimeException("加载模块资源失败", e);
        }*/
        // 读取配置
        System.out.println("模块加载 - 数据库URL:" + props.getProperty("db.url"));
        System.out.println("模块加载 - 系统名称:" + props.getProperty("system.name"));
    }
}

关键注意事项

优缺点

方式五:Apache Commons Configuration(第三方库加载)

适用场景

核心原理

Apache Commons Configuration是Apache开源项目,提供了更强大的配置加载API,封装了流处理、编码转换、异常处理等细节,支持classpath、文件系统、URL等多种资源。

实现步骤与代码示例

  1. 引入依赖(Maven):
<!-- Apache Commons Configuration 2.x -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-configuration2</artifactId>
    <version>2.10.1</version>
</dependency>
<!-- 依赖 Commons Lang 和 Commons Collections -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>
  1. 加载代码:
import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
public class CommonsConfigLoader {
    public static void main(String[] args) {
        PropertiesConfiguration config;
        try {
            // 方式1:加载classpath下的文件
            config = new PropertiesConfiguration("config.properties");
            // 方式2:加载文件系统路径
            // config = new PropertiesConfiguration("D:/config/config.properties");
            // 方式3:指定编码(默认UTF-8,无需额外处理中文)
            // config = new PropertiesConfiguration();
            // config.setEncoding("UTF-8");
            // config.load("classpath:config.properties");
        } catch (ConfigurationException e) {
            throw new RuntimeException("加载配置文件失败", e);
        }
        // 读取配置(支持默认值、类型转换)
        String dbUrl = config.getString("db.url");
        String dbUsername = config.getString("db.username");
        String systemName = config.getString("system.name", "默认系统"); // 默认值
        int dbPort = config.getInt("db.port", 3306); // 类型转换+默认值
        System.out.println("Commons加载 - 数据库URL:" + dbUrl);
        System.out.println("Commons加载 - 数据库端口:" + dbPort);
        System.out.println("Commons加载 - 系统名称:" + systemName);
    }
}

核心特性

优缺点

方式六:ServletContext.getResourceAsStream()(Web应用专属)

适用场景

核心原理

Web应用启动时,Servlet容器(Tomcat、Jetty)会创建ServletContext(Servlet上下文),通过其getResourceAsStream()方法可加载Web应用目录下的资源,路径以/开头,基准目录为Web应用根目录(WEB-INF的上级目录)。

实现步骤与代码示例

  1. 配置文件位置:WEB-INF/config/config.properties(Web应用目录)
  2. 加载代码(Servlet中):
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
@WebServlet("/configLoader")
public class ServletConfigLoader extends HttpServlet {
    private Properties props;
    // 初始化时加载配置(Servlet生命周期)
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        props = new Properties();
        // 通过ServletContext获取资源流,路径以"/"开头(基准为Web应用根目录)
        String resourcePath = "/WEB-INF/config/config.properties";
        try (InputStreamReader isr = new InputStreamReader(
                getServletContext().getResourceAsStream(resourcePath),
                StandardCharsets.UTF_8)) {
            props.load(isr);
        } catch (IOException e) {
            throw new ServletException("Web应用加载配置文件失败,路径:" + resourcePath, e);
        }
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/plain;charset=UTF-8");
        // 读取配置并响应
        String dbUrl = props.getProperty("db.url");
        String systemName = props.getProperty("system.name");
        resp.getWriter().write("Web加载 - 数据库URL:" + dbUrl + "\n");
        resp.getWriter().write("Web加载 - 系统名称:" + systemName);
    }
}

路径规则

优缺点

三、六种加载方式对比总结

加载方式适用场景核心优点核心缺点
ClassLoader.getResourceAsStream()普通Java项目、Spring Boot项目跨环境移植性强、支持JAR内资源、无需路径依赖仅加载classpath下文件
FileInputStream外部配置文件、动态指定路径可加载任意位置文件、路径灵活移植性差、需手动处理路径正确性
Spring框架(@PropertySource)Spring生态项目支持DI注入、占位符解析、多文件加载依赖Spring框架
Java 9+ Module加载模块化项目(Java 9+)资源访问可控、符合模块化规范仅支持Java 9+、需配置module-info.java
Apache Commons Configuration需高级配置特性(多格式、刷新)API简洁、功能强大、自动处理编码需引入第三方依赖
ServletContext.getResourceAsStream()Web应用安全(WEB-INF)、适配Web目录结构仅支持Web应用、依赖Servlet容器

四、最佳实践

1. 配置文件存放位置

2. 编码处理规范

3. 路径写法规范

4. 避免硬编码

# application-dev.properties(开发环境)
config.path=classpath:config-dev.properties
# application-prod.properties(生产环境)
config.path=file:/opt/config/config-prod.properties

5. 配置刷新机制

五、常见问题排查

问题现象根因分析解决方案
中文乱码未指定UTF-8编码,默认ISO-8859-1不支持中文使用InputStreamReader指定UTF-8,或框架编码配置
找不到配置文件(FileNotFoundException)路径错误(绝对路径不存在、相对路径基准错误)检查路径正确性、使用绝对路径测试、打印System.getProperty("user.dir")确认基准目录
ClassLoader加载不到文件文件未放在classpath下、路径写绝对路径移至src/main/resources、使用相对classpath路径
Spring @Value注入为null未加@PropertySource、配置文件路径错误、未扫描组件检查注解配置、路径正确性、@Component扫描范围
模块化项目加载失败模块未开放资源访问权限module-info.java中添加opens 包名 to 模块名

六、总结

Java加载Properties文件的六种方式各有适配场景,核心选择原则:

实际开发中,需结合项目类型(普通Java、Spring、Web、模块化)、配置存放位置(classpath内/外)、功能需求(动态刷新、多环境)选择合适的加载方式,并遵循编码规范、路径规范、避免硬编码等最佳实践,确保配置加载的可靠性和可维护性。

到此这篇关于Java加载Properties文件的六种方式:从基础到实战全解析的文章就介绍到这了,更多相关Java加载Properties文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文