目标
Java 程序维护一个全局的配置对象,可以在任何地方读取配置文件 application.properties
中的配置。项目启动后,从配置文件中读取配置并创建对象实例,之后就可以集中地从这个对象中获取配置信息,而不用每次加载配置时再重新读取配置、并创建新的对象,减少了性能开销。
代码实践
项目初始化与依赖引入
新建空 Maven 项目。pom.xml
引入以下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.32</version> <scope>provided</scope> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.16</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.3.12</version> </dependency> </dependencies>
|
本项目使用 Hutool 工具类简化代码的编写。
配置类
这个类定义了你的 Java 应用的默认配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package top.uuanqin.glocalconfig.config;
import lombok.Data;
@Data public class MyConfig {
private String name = "Wuanqin";
private Integer id = 10908;
}
|
配置加载工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package top.uuanqin.glocalconfig.config;
import cn.hutool.core.util.StrUtil; import cn.hutool.setting.dialect.Props;
public class ConfigUtils {
public static <T> T loadConfig(Class<T> tClass, String prefix) { return loadConfig(tClass, prefix, ""); }
public static <T> T loadConfig(Class<T> tClass, String prefix, String environment) { StringBuilder configFileBuilder = new StringBuilder("application"); if (StrUtil.isNotBlank(environment)) { configFileBuilder.append("-").append(environment); } configFileBuilder.append(".properties"); Props props = new Props(configFileBuilder.toString()); return props.toBean(tClass, prefix); } }
|
这个工具类的作用是,传入配置类、配置名称的前缀以及环境,返回填好配置信息的配置类。
Hutool 中的 Props
类
- 类 Props:Properties 文件读取封装类。继承
java.util.Properties
- 构造函数:
Props(String path)
构造,使用相对于 Class 文件根目录的相对路径。
- 方法
<T> T toBean(Class<T> beanClass, String prefix)
:将配置文件转换为 Bean,支持嵌套 Bean。
- prefix
:公共前缀,不指定前缀传 null,当指定前缀后非此前缀的属性被忽略
——hutool 5.8.29 API
Hutool 中的 StrUtil
工具类
- 继承
cn.hutool.core.text.CharSequenceUtil
类
CharSequenceUtil
中的方法:isNotBlank(CharSequence str)
。判断字符串是否为非空白,非空白的定义如下: 不为 null
不为空字符串:""
不为空格、全角空格、制表符、换行符,等不可见字符
——hutool 5.8.29 API
这个工具类的亮点在于:
- 灵活处理配置类,
loadConfig
的 tClass
参数指定生成的配置类
- 多环境配置文件的支持:通过
environment
参数,依照命名惯例,加载多环境的配置文件
- 可拓展点:你可以试着编写读取
application.yaml
配置的功能
关于 java.util.Properties
更多说明详见:java.util.Properties类操作properties文件-CSDN博客
关于 getBean
函数可看本站文章以获取更多补充:SpringBoot 中的 IoC & DI 入门
常量定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package top.uuanqin.glocalconfig.config;
public interface Constant {
String DEFAULT_CONFIG_PREFIX = "my-config"; }
|
使用单例模式维护全局对象
这里的单例模式使用了经典的双检锁单例模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package top.uuanqin.glocalconfig;
import lombok.extern.slf4j.Slf4j; import top.uuanqin.glocalconfig.config.ConfigUtils; import top.uuanqin.glocalconfig.config.Constant; import top.uuanqin.glocalconfig.config.MyConfig;
@Slf4j public class MyApplication {
private static volatile MyConfig myConfig;
public static void init(MyConfig newMyConfig) { myConfig = newMyConfig; log.info("my application init, config = {}", newMyConfig.toString()); }
public static void init() { MyConfig newMyConfig; try { newMyConfig = ConfigUtils.loadConfig(MyConfig.class, Constant.DEFAULT_CONFIG_PREFIX); } catch (Exception e) { newMyConfig = new MyConfig(); } init(newMyConfig); }
public static MyConfig getMyConfig() { if (myConfig == null) { synchronized (MyApplication.class) { if (myConfig == null) { init(); } } } return myConfig; } }
|
为了便于扩展,支持通过 public static void init(MyConfig newMyConfig)
方法传入自己的配置。
测试
调用测试
一行代码即可读取配置。
1 2 3 4 5 6 7 8 9 10
| package top.uuanqin.glocalconfig;
import top.uuanqin.glocalconfig.config.MyConfig;
public class Main { public static void main(String[] args) { MyConfig config = MyApplication.getMyConfig(); } }
|
修改配置文件
修改配置文件运行测试可以查看效果。
application.properties
:
本文参考