专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java中自定义配置文件可以如此简单

temp10 2025-04-26 21:07:31 java教程 4 ℃ 0 评论


在Java系统开发中,各种配置文件管理是非常常见且重要的工作,配置文件包括传统的键值对配置文件(properties文件),XML文件(Spring的Bean定义),YAML文件(Spring Boot中常用)等,如果系统中需要使用多个配置文件,且配置文件的类型不一样时,配置文件的管理将是一个很头疼的问题,现在有一个全新的配置文件管理工具,欢迎各位开发人员多多尝试。

依赖引用

最新版本为1.2.2,使用时请替换${version}为对应的版本号 Maven:

Java中自定义配置文件可以如此简单

<dependency>
    <groupId>org.nervousync</groupId>
    <artifactId>utils-jdk11</artifactId>
    <version>${version}</version>
</dependency>

Gradle:

Manual: compileOnly group: 'org.nervousync', name: 'utils-jdk11', version: '${version}'
Short: compileOnly 'org.nervousync:utils-jdk11:${version}'

SBT:

libraryDependencies += "org.nervousync" % "utils-jdk11" % "${version}" % "provided"

Ivy:

<dependency org="org.nervousync" name="utils-jdk11" rev="${version}"/>

配置文件的特殊之处

配置文件在Java系统中起着关键作用,它们主要用于解耦代码与环境、提高灵活性和可维护性,当系统需要同时使用多个配置文件时,拥有一个能够统一管理的配置文件管理器,将给开发工作提供很大帮助。配置文件中经常会保存一些敏感信息(包括Api Key、密钥数据、密码等),如果能够将这些敏感信息在保存时自动加密,读取时自动解密,那么可以很好的保护敏感信息,在意外泄漏配置文件时,也不会导致敏感信息泄漏。

配置文件定义

开发人员在需要定义新的配置文件时,仅需要定义一个JavaBean,并继承
org.nervousync.beans.core.BeanObject 抽象类,在JavaBean中定义好配置文件信息,在JavaBean的类定义上添加
org.nervousync.annotations.beans.OutputConfig 注解,至此配置文件已经完成。

如果使用的是XML格式的配置文件,需要在JavaBean中添加对应的JAXB的注解信息

OutputConfig注解的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | type | StringUtils.StringType | 默认为SERIALIZABLE(序列化),可选JSON、YAML、XML | |formatted| 布尔值 | true:格式化输出(方便阅读),false:所有数据在一行显示 | | encoding | 字符串 | 使用的编码集,默认为“UTF-8” |

不同 StringUtils.StringType 值对应的文件扩展名: | 数据类型 | 文件扩展名 | | :---: | :---: | | SERIALIZABLE | dat | | JSON | json | | YAML | yml 或 yaml | | XML | xml |

配置文件定义示例:

/*
 * Licensed to the Nervousync Studio (NSYC) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.nervousync.proxy;

import java.net.Proxy.Type;

import jakarta.xml.bind.annotation.*;
import org.nervousync.annotations.configs.Password;
import org.nervousync.beans.core.BeanObject;
import org.nervousync.commons.Globals;

/**
 * <h2 class="en-US">Proxy server configure</h2>
 * <h2 class="zh-CN">代理服务器配置信息</h2>
 *
 * @author Steven Wee    <a href="mailto:wmkm0113@gmail.com">wmkm0113@gmail.com</a>
 * @version $Revision: 1.0.0 $ $Date: Jan 4, 2018 16:05:54 $
 */
@XmlType(name = "proxy_config", namespace = "https://nervousync.org/schemas/proxy")
@XmlRootElement(name = "proxy_config", namespace = "https://nervousync.org/schemas/proxy")
@XmlAccessorType(XmlAccessType.NONE)
public final class ProxyConfig extends BeanObject {
    /**
     * <span class="en-US">Serial version UID</span>
     * <span class="zh-CN">序列化UID</span>
     */
    private static final long serialVersionUID = -5386443812775715018L;
    /**
     * <span class="en-US">Enumeration value of proxy type</span>
     * <span class="zh-CN">代理服务器类型枚举值</span>
     */
    @XmlElement(name = "type")
    private Type proxyType = Type.DIRECT;
    /**
     * <span class="en-US">Proxy server address</span>
     * <span class="zh-CN">代理服务器地址</span>
     */
    @XmlElement(name = "address")
    private String proxyAddress = Globals.DEFAULT_VALUE_STRING;
    /**
     * <span class="en-US">Proxy server port</span>
     * <span class="zh-CN">代理服务器端口号</span>
     */
    @XmlElement(name = "port")
    private int proxyPort = Globals.DEFAULT_VALUE_INT;
    /**
     * <span class="en-US">Authenticate username</span>
     * <span class="zh-CN">身份认证用户名</span>
     */
    @XmlElement(name = "username")
    private String userName = Globals.DEFAULT_VALUE_STRING;
    /**
     * <span class="en-US">Authenticate password</span>
     * <span class="zh-CN">身份认证密码</span>
     */
    @XmlElement(name = "password")
    private String password = Globals.DEFAULT_VALUE_STRING;
    /**
     * <span class="en-US">Last modified timestamp</span>
     * <span class="zh-CN">最后修改时间戳</span>
     */
    @XmlElement(name = "last_modified")
    private long lastModified = Globals.DEFAULT_VALUE_LONG;

    /**
     * <h3 class="en-US">Constructor method for ProxyConfig</h3>
     * <h3 class="zh-CN">ProxyConfig构造方法</h3>
     */
    public ProxyConfig() {
    }

    /**
     * <h3 class="en-US">Static method for create redirect ProxyConfig instance</h3>
     * <h3 class="zh-CN">静态方法用于创建无代理的代理服务器配置信息实例对象</h3>
     *
     * @return <span class="en-US">Generated ProxyConfig instance</span>
     * <span class="zh-CN">生成的代理服务器配置信息实例对象</span>
     */
    public static ProxyConfig redirect() {
        return new ProxyConfig();
    }

    /**
     * <h3 class="en-US">Getter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Getter方法</h3>
     *
     * @return <span class="en-US">Enumeration value of proxy type</span>
     * <span class="zh-CN">代理服务器类型枚举值</span>
     */
    public Type getProxyType() {
        return proxyType;
    }

    /**
     * <h3 class="en-US">Setter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Setter方法</h3>
     *
     * @param proxyType <span class="en-US">Enumeration value of proxy type</span>
     *                  <span class="zh-CN">代理服务器类型枚举值</span>
     */
    public void setProxyType(Type proxyType) {
        this.proxyType = proxyType;
    }

    /**
     * <h3 class="en-US">Getter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Getter方法</h3>
     *
     * @return <span class="en-US">Proxy server address</span>
     * <span class="zh-CN">代理服务器地址</span>
     */
    public String getProxyAddress() {
        return proxyAddress;
    }

    /**
     * <h3 class="en-US">Setter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Setter方法</h3>
     *
     * @param proxyAddress <span class="en-US">Proxy server address</span>
     *                     <span class="zh-CN">代理服务器地址</span>
     */
    public void setProxyAddress(String proxyAddress) {
        this.proxyAddress = proxyAddress;
    }

    /**
     * <h3 class="en-US">Getter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Getter方法</h3>
     *
     * @return <span class="en-US">Proxy server port</span>
     * <span class="zh-CN">代理服务器端口号</span>
     */
    public int getProxyPort() {
        return proxyPort;
    }

    /**
     * <h3 class="en-US">Setter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Setter方法</h3>
     *
     * @param proxyPort <span class="en-US">Proxy server port</span>
     *                  <span class="zh-CN">代理服务器端口号</span>
     */
    public void setProxyPort(int proxyPort) {
        this.proxyPort = proxyPort;
    }

    /**
     * <h3 class="en-US">Getter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Getter方法</h3>
     *
     * @return <span class="en-US">Authenticate username</span>
     * <span class="zh-CN">身份认证用户名</span>
     */
    public String getUserName() {
        return userName;
    }

    /**
     * <h3 class="en-US">Setter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Setter方法</h3>
     *
     * @param userName <span class="en-US">Authenticate username</span>
     *                 <span class="zh-CN">身份认证用户名</span>
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * <h3 class="en-US">Getter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Getter方法</h3>
     *
     * @return <span class="en-US">Authenticate password</span>
     * <span class="zh-CN">身份认证密码</span>
     */
    public String getPassword() {
        return password;
    }

    /**
     * <h3 class="en-US">Setter method for proxy type</h3>
     * <h3 class="zh-CN">代理服务器类型的Setter方法</h3>
     *
     * @param password <span class="en-US">Authenticate password</span>
     *                 <span class="zh-CN">身份认证密码</span>
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * <h3 class="en-US">Getter method for the last modified timestamp</h3>
     * <h3 class="zh-CN">最后修改时间戳的Getter方法</h3>
     *
     * @return <span class="en-US">Last modified timestamp</span>
     * <span class="zh-CN">最后修改时间戳</span>
     */
    public long getLastModified() {
        return this.lastModified;
    }

    /**
     * <h3 class="en-US">Setter method for the last modified timestamp</h3>
     * <h3 class="zh-CN">最后修改时间戳的Setter方法</h3>
     *
     * @param lastModified <span class="en-US">Last modified timestamp</span>
     *                     <span class="zh-CN">最后修改时间戳</span>
     */
    public void setLastModified(final long lastModified) {
        this.lastModified = lastModified;
    }
}

配置文件管理器

在调用
org.nervousync.configs.ConfigureManager 的 getInstance() 静态方法时,系统会自动初始化配置文件管理器,配置文件的默认保存位置为当前用户工作目录下名为“.configs”的文件夹中,如果需要自定义配置文件的保存位置,需要调用
org.nervousync.configs.ConfigureManager 的 initialize 静态方法,将自定义保存位置路径字符串作为参数传入。

注意: 配置文件管理器使用单例模式运行。

1.检查配置文件是否存在

调用
org.nervousync.configs.ConfigureManager 实例对象的 checkExists 方法检查配置文件是否存在,方法返回值类型为布尔值,文件存在返回“true”,文件不存在返回“false”。

checkExists方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | targetClass | Class | 配置信息定义类 | | suffix | 字符串 | 配置文件自定义后缀,用于区分同一类型的不同配置信息(可选参数) |

2.写入配置文件

调用
org.nervousync.configs.ConfigureManager 实例对象的 saveConfigure 方法保存配置文件对象,方法返回值类型为布尔值,保存成功返回“true”,保存失败返回“false”。

saveConfigure方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | beanObject |
org.nervousync.beans.core.BeanObject | 配置信息实例对象 | | suffix | 字符串 | 配置文件自定义后缀,用于区分同一类型的不同配置信息(可选参数) |

3.读取配置文件

调用
org.nervousync.configs.ConfigureManager 实例对象的 readConfigure 方法读取配置文件,方法返回值为给定配置信息定义类的实例对象,文件存在返回实例对象,文件不存在返回 null 。

readConfigure方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | targetClass | Class | 配置信息定义类 | | suffix | 字符串 | 配置文件自定义后缀,用于区分同一类型的不同配置信息(可选参数) |

4.删除配置文件

调用
org.nervousync.configs.ConfigureManager 实例对象的 removeConfigure 方法读取配置文件,方法返回值类型为布尔值,删除成功返回“true”,删除失败返回“false”。

removeConfigure方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | targetClass | Class | 配置信息定义类 | | suffix | 字符串 | 配置文件自定义后缀,用于区分同一类型的不同配置信息(可选参数) |

注意: 如果suffix参数为空,则删除所有类型为给定配置信息定义类的配置文件。

5.转换配置文件类型

调用
org.nervousync.configs.ConfigureManager 实例对象的 convertType 方法读取配置文件,方法返回值类型为布尔值,转换成功返回“true”,转换失败返回“false”。

removeConfigure方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | targetClass | Class | 配置信息定义类 | | originalType | StringUtils.StringType | 原始数据类型 | | targetType | StringUtils.StringType | 转换后的数据类型 | | suffix | 字符串 | 配置文件自定义后缀,用于区分同一类型的不同配置信息(可选参数) |

注意: 如果suffix参数为空,则转换所有类型为给定配置信息定义类的配置文件。

敏感信息的保护

当某些字段保存的数据为敏感信息时,仅需要在字段上使用
org.nervousync.annotations.configs.Password 标注即可,默认使用AES256加密算法来保护敏感信息,配置信息管理器会在保存文件时自动加密该字段,在读取文件时自动解密该字段。

示例代码:

/**
 * <span class="en-US">Authenticate password</span>
 * <span class="zh-CN">身份认证密码</span>
 */
@Password
@XmlElement(name = "password")
private String password = Globals.DEFAULT_VALUE_STRING;

使用自定义的加密算法

1.配置加密算法

调用
org.nervousync.security.factory.SecureFactory 的 initConfig 静态方法初始化加密算法配置。

initConfig方法的参数:

| 参数名 | 数据类型 | 备注 | | :-----: | :-----: | :-----: | | secureName | 字符串 | 安全配置名称 | | secureAlgorithm |
SecureFactory.SecureAlgorithm | 使用的加密算法,支持:RSA1024, RSA2048, SM2, AES128, AES192, AES256, DES, TRIPLE_DES, SM4 |

2.使用安全配置

修改
org.nervousync.annotations.configs.Password 标注的 value 参数为刚刚初始化的安全配置名称,即可使用自定义的加密算法来保护敏感信息。

配置文件的自动加载

开发人员可以通过简单的修改来实现配置文件的自动加载,省去读取配置文件的代码操作。

1.定义配置文件属性

添加类型为配置文件的属性,并使用
org.nervousync.annotations.configs.Configuration 标注,可以通过标注的 value 参数修改需要使用的配置文件后缀名,将包含属性类型为配置文件的类继承
org.nervousync.configs.AutoConfig 抽象类。

2.初始化并测试自动加载

通过 new 创建类的实例对象,可以发现创建的实例对象中,类型为配置文件的属性值已经自动加载完成(如果配置文件存在)。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表