Spring Boot如何通过主properties文件按需加载WebService对应配置文件
Spring动态加载多WebService子配置实现方案
核心逻辑:以固定路径的主配置为入口,启动时动态加载所有子配置文件到Spring环境,既支持常规配置读取,也支持按服务维度遍历读取专属配置,替代原硬编码加载单个固定配置的实现。
实现步骤
- 替换原@PropertySource加载的固定文件为入口主配置
webservices.properties - 配置类初始化阶段遍历主配置中存储的所有子配置路径,逐份加载子配置并注册到Spring环境
- 业务逻辑中可直接读取全局配置,也可按服务维度读取专属配置源,避免重名key冲突
完整代码实现
import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.support.PropertiesLoaderUtils; import java.util.Properties; import java.util.Map; // 固定加载主配置入口文件 @PropertySource(value = "file:src/main/resources/webservices.properties", name = "main.webservice.props") @Configuration public class Config { @Autowired private ConfigurableEnvironment env; // 容器启动时自动执行,加载所有子配置 @PostConstruct public void loadAllSubConfigs() throws Exception { MutablePropertySources propertySources = env.getPropertySources(); // 获取主配置中存储的所有子配置路径映射 PropertiesPropertySource mainConfigSource = (PropertiesPropertySource) propertySources.get("main.webservice.props"); Map<String, Object> servicePathMappings = mainConfigSource.getSource(); for (Map.Entry<String, Object> entry : servicePathMappings.entrySet()) { String serviceKey = entry.getKey(); String configFilePath = entry.getValue().toString(); // 加载文件系统中的子配置文件 Properties subConfigProps = PropertiesLoaderUtils.loadProperties(new FileSystemResource(configFilePath)); // 将子配置注册到环境中,每个配置源使用独立命名避免冲突 propertySources.addLast(new PropertiesPropertySource("webservice." + serviceKey + ".props", subConfigProps)); } } @Bean public void doStuff() { // 1. 常规方式读取配置(注意重名key会按配置优先级取) String propValue = env.getProperty("key1"); // 2. 遍历所有WebService读取专属配置(完全隔离,无重名冲突问题) MutablePropertySources propertySources = env.getPropertySources(); PropertiesPropertySource mainConfigSource = (PropertiesPropertySource) propertySources.get("main.webservice.props"); for (String serviceKey : mainConfigSource.getSource().keySet()) { PropertiesPropertySource serviceConfig = (PropertiesPropertySource) propertySources.get("webservice." + serviceKey + ".props"); // 读取当前服务的对应配置 String key1 = (String) serviceConfig.getProperty("key1"); String key2 = (String) serviceConfig.getProperty("key2"); String key3 = (String) serviceConfig.getProperty("key3"); // 执行业务逻辑 System.out.printf("服务%s加载配置完成:key1=%s, key2=%s, key3=%s%n", serviceKey, key1, key2, key3); } } }
注意事项
- Spring Boot 2.x版本中
@PostConstruct注解需从javax.annotation.PostConstruct导入,3.x及以上版本使用jakarta.annotation.PostConstruct导入即可 - 不同子配置存在重名key时,不要直接从全局Environment读取,优先从对应服务的独立PropertySource对象读取,避免配置覆盖问题
- 新增或移除WebService配置时,只需要修改主配置中的路径条目,无需调整代码,重启服务即可自动生效
- 若需要配置热更新,可将子配置加载逻辑抽为独立方法,配合文件监听机制,检测到文件变动时替换对应PropertySource即可实现不重启更新配置
内容的提问来源于stack exchange,提问作者Yassir K
相关产品推荐
相关产品推荐

