Java:Properties工具类配置

提示

有时候会需要读取配置文件(.properties),无论是项目内还是项目外,于是从网上收集了一个工具类,进行了一些优化.

请注意:代码基于Jdk 9 编译.

代码

package xyz.suancaiyu.util;

import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Properties 工具类
 *
 * @Author: puruidong
 * @Version: 2018/3/15  17:29
 */
public class PropertiesUtil {


    private static final String APPLICATIONFILEPATH = "F:\\conf\\application.properties";

    private PropertiesUtil() {
    }

    private static PropertiesUtil propertiesUtil = null;

    public static PropertiesUtil getInstance() {
        if (propertiesUtil == null) {
            propertiesUtil = new PropertiesUtil();
        }
        return propertiesUtil;
    }

    /**
     * 根据文件名获取Properties对象
     * <p>
     * <p>
     * 读取项目内部配置文件:
     * <p>
     * <p>
     * in = PropertiesUtil.class.getClassLoader().getResourceAsStream(Constats.APPLICATIONFILEPATH);
     *
     * @return
     */
    public Properties read() {
        try(InputStream in = new FileInputStream(new File(APPLICATIONFILEPATH))) {
            Properties prop = new Properties();
            if (in == null) {
                return null;
            }
            prop.load(in);
            return prop;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据文件名和键名获取值
     *
     * @param key
     * @return
     */
    public String readKeyValue(String key) {
        Properties prop = read();
        if (prop != null) {
            return prop.getProperty(key);
        }
        return null;
    }

    /**
     * 根据键名获取值
     *
     * @param prop
     * @param key
     * @return
     */
    public String readKeyValue(Properties prop, String key) {
        if (prop != null) {
            return prop.getProperty(key);
        }
        return null;
    }

    /**
     * 写入
     *
     * @param fileName
     * @param key
     * @param value
     */
    public void writeValueByKey(String fileName, String key, String value) {
        Map<String, String> properties = new HashMap<>();
        properties.put(key, value);
        writeValues(properties);
    }

    /**
     * 写入
     *
     * @param properties
     */
    public void writeValues(Map<String, String> properties) {
        try(InputStream in =new FileInputStream(new File(APPLICATIONFILEPATH));
            OutputStream out = new FileOutputStream(APPLICATIONFILEPATH);) {
            /*
            如果是项目内的配置文件,需要使用下面这一行代码.

            in = PropertiesUtil.class.getClassLoader().getResourceAsStream(APPLICATIONFILEPATH);
             */
            if (in == null) {
                throw new RuntimeException("读取的文件(" + APPLICATIONFILEPATH + ")不存在,请确认!");
            }
            Properties prop = new Properties();
            prop.load(in);
            // 项目内部配置文件才用这个.
            // String path =  PropertiesUtil.class.getResource( APPLICATIONFILEPATH).getPath();

            if (properties != null) {
                Set<String> set = properties.keySet();
                for (String string : set) {
                    prop.setProperty(string, properties.get(string));
                }
            }
            prop.store(out, "update properties");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        System.out.println(PropertiesUtil.getInstance().readKeyValue("libpath"));
        Map<String, String> maps = new HashMap<>(2);
        maps.put("add", "true");
        PropertiesUtil.getInstance().writeValues(maps);


    }

}

Java:Log4j2使用外部配置文件

使用异步写入日志

Log4j2可以使用异步的方式写入日志,这样可以增加一些性能.但是不能在配置文件中记录行号,记录行号或位置会导致速度变慢.(参考)

异步写入需要设置一个系统变量:

// java.lang.System;JDK自带,写在这只是为了提示.
System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
        

同时还需要 disruptor最新版,具体可以看下面的maven配置.

java标志

使用外部配置文件

使用外部配置文件的方式很简单,直接用下面的代码即可实现,但是注意必须要在获取Logger对象之前设置:

// import org.apache.logging.log4j.core.config.Configurator;
Configurator.initialize(null, "F:\\conf\\log4j2.properties");

外部配置文件

可以直接放在项目外部任意位置,只要Java有权限访问到即可.

文件类型是:properties,因为Log4j2支持properties,yaml/yml,json,xml等类型的配置文件.

# log4j2.properties
# 配置文件参考了网上的,作了部分修改.

status = error
name = PropertiesConfig

property.filename = logs/run.log

filters = threshold

filter.threshold.type = ThresholdFilter
filter.threshold.level = debug

appender.console.type = Console
appender.console.name = STDOUT
appender.console.target = SYSTEM_OUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ] %m%n

appender.I.type = RollingFile
appender.I.name = InfoRollingFile
appender.I.fileName = logs/info-${date:yyyy-MM-dd}.log
appender.I.filePattern = logs/info_%d{yyyy-MM-dd}_%i.log
appender.I.layout.type = PatternLayout
appender.I.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ] %m%n
appender.I.policies.type = Policies
appender.I.policies.time.type = TimeBasedTriggeringPolicy
appender.I.policies.time.interval = 1
appender.I.append = true
appender.I.policies.time.modulate = true
appender.I.policies.size.type = SizeBasedTriggeringPolicy
appender.I.policies.size.size=20M
appender.I.strategy.type = DefaultRolloverStrategy
appender.I.strategy.max = 100

# [ %L ]
appender.E.type = RollingFile
appender.E.name = ErrorRollingFile
appender.E.fileName = logs/error-${date:yyyy-MM-dd}.log
appender.E.filePattern = logs/error_%d{yyyy-MM-dd}_i.log
appender.E.layout.type = PatternLayout
appender.E.layout.pattern = %-d{yyyy-MM-dd HH:mm:ss} [ %p ] [ %c ]  %m%n
appender.E.policies.type = Policies
appender.E.policies.time.type = TimeBasedTriggeringPolicy
appender.E.policies.time.interval = 1
appender.E.append = true
appender.E.policies.time.modulate = true
appender.E.policies.size.type = SizeBasedTriggeringPolicy
appender.E.policies.size.size=20M
appender.E.strategy.type = DefaultRolloverStrategy
appender.E.strategy.max = 100

rootLogger.level = info
rootLogger.appenderRefs = stdout,I,E
rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRef.I.ref = InfoRollingFile
rootLogger.appenderRef.I.level = info
rootLogger.appenderRef.E.ref = ErrorRollingFile
rootLogger.appenderRef.E.level = error

完整代码

Maven: pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>xyz.suancaiyu</groupId>
    <artifactId>Log4jTest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <log4j2version>2.10.0</log4j2version>
        <disruptorversion>3.4.1</disruptorversion>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j2version}</version>
        </dependency>
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>${disruptorversion}</version>
        </dependency>

    </dependencies>

</project>
package xyz.suancaiyu.main;

import org.apache.logging.log4j.core.config.Configurator;
import org.slf4j.LoggerFactory;



/**
 * @Author: puruidong
 * @Version: 2018/3/15  15:24
 */
public class Main {

    private static org.slf4j.Logger logger = null;

    static {
        /**
         * 使用异步方式调用Log4j2记录日志,但是配置文件中禁止使用记录行号信息等配置。
         * 否则会影响性能。
         *
         */
        System.setProperty("log4j2.contextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
        // 加载外部配置文件.
        // 位置随意,但是别忘了先创建并写入配置数据.
        Configurator.initialize(null, "F:\\conf\\log4j2.properties");
        logger = LoggerFactory.getLogger(Main.class);
    }

    public static void main(String[] args) {
        logger.info("日志模块加载完毕...");
        logger.info("加载系统所需Jar包...");
        logger.info("加载系统所需Jar包完毕...");
        logger.info("执行返回结果:{}", "你好");
        logger.error("系统执行错误:错误信息,{}","错误");
        logger.info("程序执行完毕!");
        System.out.println("程序执行完毕!");
    }

}

到此.