ruoyi的spring cloud项目详解(十三)

 继续学习吧,家人们

 ruoyi的spring cloud项目详解(十二)-CSDN博客

com/ruoyi/common/utils/Threads.java

package com.ruoyi.common.utils;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 线程相关工具类.
 * 
 * @author ruoyi
 */
public class Threads
{
    private static final Logger logger = LoggerFactory.getLogger(Threads.class);

    /**
     * sleep等待,单位为毫秒
     */
    public static void sleep(long milliseconds)
    {
        try
        {
            Thread.sleep(milliseconds);
        }
        catch (InterruptedException e)
        {
            return;
        }
    }

    /**
     * 停止线程池
     * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
     * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
     * 如果仍人超時,則強制退出.
     * 另对在shutdown时线程本身被调用中断做了处理.
     */
    public static void shutdownAndAwaitTermination(ExecutorService pool)
    {
        if (pool != null && !pool.isShutdown())
        {
            pool.shutdown();
            try
            {
                if (!pool.awaitTermination(120, TimeUnit.SECONDS))
                {
                    pool.shutdownNow();
                    if (!pool.awaitTermination(120, TimeUnit.SECONDS))
                    {
                        logger.info("Pool did not terminate");
                    }
                }
            }
            catch (InterruptedException ie)
            {
                pool.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 打印线程异常信息
     */
    public static void printException(Runnable r, Throwable t)
    {
        if (t == null && r instanceof Future<?>)
        {
            try
            {
                Future<?> future = (Future<?>) r;
                if (future.isDone())
                {
                    future.get();
                }
            }
            catch (CancellationException ce)
            {
                t = ce;
            }
            catch (ExecutionException ee)
            {
                t = ee.getCause();
            }
            catch (InterruptedException ie)
            {
                Thread.currentThread().interrupt();
            }
        }
        if (t != null)
        {
            logger.error(t.getMessage(), t);
        }
    }
}

以下是对这段 Java 代码的逐块分析:

package com.ruoyi.common.utils;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

这部分代码声明了包名,并导入了必要的类。包括用于处理异步任务异常的CancellationExceptionExecutionException,用于管理线程池的ExecutorServiceFuture,用于指定时间单位的TimeUnit,以及用于日志记录的LoggerLoggerFactory

/**
 * 线程相关工具类.
 * 
 * @author ruoyi
 */
public class Threads {

这是一个名为Threads的公共类的开始,带有一个 JavaDoc 注释,表明这个类是一个线程相关的工具类,作者是 “ruoyi”。

    private static final Logger logger = LoggerFactory.getLogger(Threads.class);

创建了一个私有静态的日志对象logger,用于记录线程相关的日志信息。这个日志对象通过LoggerFactory.getLogger(Threads.class)获取,与Threads类相关联。

    /**
     * sleep等待,单位为毫秒
     */
    public static void sleep(long milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            return;
        }
    }

这个静态方法sleep接受一个参数milliseconds,表示要休眠的时间长度,单位为毫秒。它使用Thread.sleep(milliseconds)来使当前线程休眠指定的时间。如果在休眠过程中被中断,捕获InterruptedException异常并直接返回,不做进一步处理。

    /**
     * 停止线程池
     * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
     * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
     * 如果仍人超時,則強制退出.
     * 另对在shutdown时线程本身被调用中断做了处理.
     */
    public static void shutdownAndAwaitTermination(ExecutorService pool) {
        if (pool!= null &&!pool.isShutdown()) {
            pool.shutdown();
            try {
                if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
                    pool.shutdownNow();
                    if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
                        logger.info("Pool did not terminate");
                    }
                }
            } catch (InterruptedException ie) {
                pool.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

这个静态方法shutdownAndAwaitTermination用于安全地停止一个线程池。

首先,检查传入的线程池pool是否不为null且未处于已关闭状态。如果满足条件,则先调用线程池的shutdown方法,停止接收新任务并尝试完成所有已存在任务。

然后,使用pool.awaitTermination(120, TimeUnit.SECONDS)等待线程池中的任务完成,如果在 120 秒内未完成,则调用shutdownNow方法,取消在工作队列中等待的任务,并中断所有阻塞的任务。

如果再次等待 120 秒后仍未完成,则使用日志对象记录信息表示线程池未正常终止。

在等待过程中,如果捕获到InterruptedException异常,则调用pool.shutdownNow方法,并中断当前线程。

    /**
     * 打印线程异常信息
     */
    public static void printException(Runnable r, Throwable t) {
        if (t == null && r instanceof Future<?>) {
            try {
                Future<?> future = (Future<?>) r;
                if (future.isDone()) {
                    future.get();
                }
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
        if (t!= null) {
            logger.error(t.getMessage(), t);
        }
    }
}

这个静态方法printException用于打印线程执行过程中的异常信息。

如果传入的异常对象tnull,并且参数r是一个Future对象,则尝试从Future对象中获取异步任务的结果。如果在获取结果过程中出现CancellationException异常,则将异常对象设置为ce;如果出现ExecutionException异常,则获取其原因并设置为异常对象t;如果出现InterruptedException异常,则中断当前线程。

如果异常对象t不为null,则使用日志对象记录异常信息,包括异常消息和堆栈跟踪。

以下是对这段 Java 代码的分析:

一、功能概述

这个类Threads是一个线程相关的工具类,提供了一些实用的方法来处理线程的操作,包括线程休眠、停止线程池和打印线程异常信息等功能。

二、代码详解

  1. 导入依赖和定义日志对象

    • import java.util.concurrent.CancellationException;:用于处理异步任务被取消时的异常。
    • import java.util.concurrent.ExecutionException;:用于处理异步任务执行时的异常。
    • import java.util.concurrent.ExecutorService;:线程池接口,用于管理线程的执行。
    • import java.util.concurrent.Future;:用于表示异步任务的结果。
    • import java.util.concurrent.TimeUnit;:时间单位枚举,用于指定时间的单位。
    • import org.slf4j.Logger;:日志接口,用于记录日志信息。
    • import org.slf4j.LoggerFactory;:日志工厂类,用于创建日志对象。
    • private static final Logger logger = LoggerFactory.getLogger(Threads.class);:创建一个日志对象,用于记录线程相关的日志信息。
  2. 方法分析

    • sleep(long milliseconds)

      • 这个方法用于使当前线程休眠指定的时间,单位为毫秒。
      • 使用Thread.sleep(milliseconds)来实现线程休眠,如果在休眠过程中被中断,则捕获InterruptedException异常并直接返回,不做进一步处理。
    • shutdownAndAwaitTermination(ExecutorService pool)

      • 这个方法用于安全地停止一个线程池。
      • 首先检查传入的线程池是否不为null且未处于已关闭状态。如果满足条件,则先调用线程池的shutdown方法,停止接收新任务并尝试完成所有已存在任务。
      • 然后使用pool.awaitTermination(120, TimeUnit.SECONDS)等待线程池中的任务完成,如果在 120 秒内未完成,则调用shutdownNow方法,取消在工作队列中等待的任务,并中断所有阻塞的任务。
      • 如果再次等待 120 秒后仍未完成,则记录日志信息表示线程池未正常终止。
      • 在等待过程中,如果捕获到InterruptedException异常,则调用pool.shutdownNow方法,并中断当前线程。
    • printException(Runnable r, Throwable t)

      • 这个方法用于打印线程执行过程中的异常信息。
      • 如果传入的异常对象tnull,并且参数r是一个Future对象,则尝试从Future对象中获取异步任务的结果。如果在获取结果过程中出现CancellationException异常,则将异常对象设置为ce;如果出现ExecutionException异常,则获取其原因并设置为异常对象t;如果出现InterruptedException异常,则中断当前线程。
      • 如果异常对象t不为null,则使用日志对象记录异常信息,包括异常消息和堆栈跟踪。

三、使用场景和注意事项

  • 使用场景:

    • 在多线程应用程序中,可以使用这些方法来管理线程的执行和处理线程的异常情况。例如,可以使用sleep方法在特定场景下让线程暂停一段时间;使用shutdownAndAwaitTermination方法在应用程序关闭时安全地停止线程池;使用printException方法在出现异常时记录线程的错误信息。
  • 注意事项:

    • 在使用sleep方法时,要注意线程被中断的情况,可能需要在合适的地方处理中断异常。
    • 在使用shutdownAndAwaitTermination方法时,要根据实际情况调整等待时间,以确保线程池能够正常停止。同时,要注意在等待过程中可能出现的中断异常,及时处理以避免程序异常终止。
    • 在使用printException方法时,要确保正确地传入参数,以便能够准确地打印线程的异常信息。

com/ruoyi/common/utils/ToolUtil.java

package com.ruoyi.common.utils;

import java.io.File;

/**
 * <p>Title: </p>
 * <p>Description: 高频方法集合类</p>
 * <p>Copyright: Copyright (c) 2019-08-19 14:51</p>
 * <p>Company: </p>
 * @version 1.0
 * @author: zmr
 */
public class ToolUtil
{
    /**
     * 获取临时目录
     * @author zmr
     */
    public static String getTempPath()
    {
        return System.getProperty("java.io.tmpdir");
    }

    /**
     * 获取当前项目工作目录
     * @return
     * @author zmr
     */
    public static String getUserDir()
    {
        return System.getProperty("user.dir");
    }

    /**
     * 获取临时下载目录
     * @return
     * @author zmr
     */
    public static String getDownloadPath()
    {
        return getTempPath() + File.separator + "download" + File.separator;
    }
}

以下是对这段 Java 代码的逐块分析:

package com.ruoyi.common.utils;

import java.io.File;

这部分代码声明了包名,并导入了java.io.File类,用于处理文件和目录相关的操作。

/**
 * <p>Title: </p>
 * <p>Description: 高频方法集合类</p>
 * <p>Copyright: Copyright (c) 2019 - 08 - 19 14:51</p>
 * <p>Company: </p>
 * @version 1.0
 * @author: zmr
 */
public class ToolUtil {

这是一个名为ToolUtil的公共类的开始,带有一些 JavaDoc 注释,描述了这个类的用途、版权信息、版本号和作者信息。

    /**
     * 获取临时目录
     * @author zmr
     */
    public static String getTempPath() {
        return System.getProperty("java.io.tmpdir");
    }

这个静态方法getTempPath用于获取系统的临时目录。它通过System.getProperty("java.io.tmpdir")获取系统属性中指定的临时目录路径,并返回该路径。

    /**
     * 获取当前项目工作目录
     * @return
     * @author zmr
     */
    public static String getUserDir() {
        return System.getProperty("user.dir");
    }

这个静态方法getUserDir用于获取当前项目的工作目录。它通过System.getProperty("user.dir")获取系统属性中指定的用户目录路径,并返回该路径。

    /**
     * 获取临时下载目录
     * @return
     * @author zmr
     */
    public static String getDownloadPath() {
        return getTempPath() + File.separator + "download" + File.separator;
    }

这个静态方法getDownloadPath用于获取临时下载目录。它首先调用getTempPath()获取系统临时目录,然后在临时目录下拼接"download"文件夹路径,最后通过File.separator确保在不同操作系统下路径分隔符的正确使用,并返回临时下载目录路径。

以下是对这段 Java 代码的分析:

一、功能概述

这个类ToolUtil是一个工具类,提供了一些高频使用的方法,主要用于获取系统的临时目录、当前项目工作目录和临时下载目录。

二、代码详解

  1. 类的定义和注释

    • public class ToolUtil:定义了一个名为ToolUtil的公共类。
    • @version 1.0@author: zmr:这是 JavaDoc 风格的注释,分别表示类的版本号和作者信息。
  2. 方法分析

    • getTempPath()

      • 这个方法用于获取系统的临时目录。
      • 通过System.getProperty("java.io.tmpdir")获取系统属性中指定的临时目录路径,并返回该路径。
    • getUserDir()

      • 这个方法用于获取当前项目的工作目录。
      • 通过System.getProperty("user.dir")获取系统属性中指定的用户目录路径,并返回该路径。
    • getDownloadPath()

      • 这个方法用于获取临时下载目录。
      • 首先调用getTempPath()获取系统临时目录,然后在临时目录下拼接"download"文件夹路径,最后通过File.separator确保在不同操作系统下路径分隔符的正确使用,并返回临时下载目录路径。

三、使用场景和注意事项

  • 使用场景:

    • 在需要获取系统临时目录、当前项目工作目录或创建临时下载目录的场景中,可以使用这个工具类的方法。例如,在文件下载、临时文件存储等操作中,可以使用这些方法来确定合适的目录位置。
  • 注意事项:

    • 在使用这些方法获取的目录路径时,需要确保对目录有适当的读写权限。
    • 不同操作系统的临时目录和用户目录可能不同,需要考虑跨平台的兼容性。
    • 如果在使用临时下载目录时,需要注意及时清理不再需要的文件,以避免占用过多磁盘空间。

com/ruoyi/common/utils/ValidatorUtils.java

package com.ruoyi.common.utils;

import com.ruoyi.common.exception.base.BaseException;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

/**
 * hibernate-validator校验工具类
 * 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
 */
public class ValidatorUtils
{
    private static Validator validator;
    static
    {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

    /**
     * 校验对象
     * @param object        待校验对象
     * @param groups        待校验的组
     * @throws BaseException  校验不通过,则报BaseException异常
     */
    public static void validateEntity(Object object, Class<?> ... groups) throws BaseException
    {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty())
        {
            ConstraintViolation<Object> constraint = (ConstraintViolation<Object>) constraintViolations.iterator()
                    .next();
            throw new BaseException(constraint.getMessage());
        }
    }
}

以下是对这段 Java 代码的逐块分析:

package com.ruoyi.common.utils;

import com.ruoyi.common.exception.base.BaseException;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

这部分代码声明了包名,并导入了必要的类。包括自定义的异常类BaseException,用于存储校验结果的集合类型Set,表示违反约束的对象ConstraintViolation,用于构建验证器工厂的类Validation,以及用于执行对象校验的接口Validator

/**
 * hibernate-validator校验工具类
 * 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
 */
public class ValidatorUtils {

这是一个名为ValidatorUtils的公共类的开始,带有一个 JavaDoc 注释,表明这个类是用于 Hibernate Validator 校验的工具类,并提供了参考文档链接。

    private static Validator validator;
    static {
        validator = Validation.buildDefaultValidatorFactory().getValidator();
    }

声明了一个私有静态的Validator对象validator,并在静态初始化块中初始化它。通过调用Validation.buildDefaultValidatorFactory()创建一个默认的验证器工厂,然后从工厂中获取一个验证器。

    /**
     * 校验对象
     * @param object        待校验对象
     * @param groups        待校验的组
     * @throws BaseException  校验不通过,则报BaseException异常
     */
    public static void validateEntity(Object object, Class<?>... groups) throws BaseException {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty()) {
            ConstraintViolation<Object> constraint = (ConstraintViolation<Object>) constraintViolations.iterator().next();
            throw new BaseException(constraint.getMessage());
        }
    }
}

这个静态方法validateEntity用于校验给定的对象。

接受一个要校验的对象object和一个可变参数的校验组groups

使用validator.validate(object, groups)对对象进行校验,并返回一个包含违反约束的集合。如果集合不为空,表示校验不通过。

如果校验不通过,从集合中获取第一个违反约束的对象,提取其错误消息,并抛出一个BaseException异常,将错误消息传递给异常构造函数。

以下是对这段 Java 代码的分析:

一、功能概述

这个类ValidatorUtils是一个用于进行 Hibernate Validator 校验的工具类。它提供了一个方法来校验给定的对象,并在校验不通过时抛出一个自定义的BaseException异常。

二、代码详解

  1. 导入依赖

    • import com.ruoyi.common.exception.base.BaseException;:导入自定义的异常类,用于在校验不通过时抛出异常。
    • import java.util.Set;:用于存储校验结果的集合类型。
    • import javax.validation.ConstraintViolation;:表示违反约束的对象。
    • import javax.validation.Validation;:用于构建验证器工厂的类。
    • import javax.validation.Validator;:用于执行对象校验的接口。
  2. 静态变量和初始化块

    • private static Validator validator;:声明一个静态的Validator对象,用于执行校验操作。
    • static { validator = Validation.buildDefaultValidatorFactory().getValidator(); }:在类加载时初始化validator对象,通过调用Validation.buildDefaultValidatorFactory()创建一个默认的验证器工厂,然后从工厂中获取一个验证器。
  3. 方法分析

    • validateEntity(Object object, Class<?>... groups)
      • 这个方法接受一个要校验的对象object和一个可变参数的校验组groups
      • 使用validator.validate(object, groups)对对象进行校验,并返回一个包含违反约束的集合。如果集合不为空,表示校验不通过。
      • 如果校验不通过,从集合中获取第一个违反约束的对象,提取其错误消息,并抛出一个BaseException异常,将错误消息传递给异常构造函数。

三、使用场景和注意事项

  • 使用场景:

    • 在应用程序中,当需要对对象进行校验时,可以使用这个工具类。例如,在数据输入、对象创建或更新等场景中,可以调用validateEntity方法来确保对象满足特定的约束条件。
  • 注意事项:

    • 需要确保被校验的对象上正确地添加了 Hibernate Validator 的约束注解。
    • 在处理BaseException异常时,需要根据具体的应用场景进行适当的错误处理和日志记录。
    • 校验组的使用可以根据具体需求进行灵活配置,以实现不同场景下的校验逻辑。

com/ruoyi/common/utils/YamlUtil.java

package com.ruoyi.common.utils;

import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import com.ruoyi.common.utils.StringUtils;

/**
 * 配置处理工具类
 * 
 * @author yml
 */
public class YamlUtil
{
    public static Map<?, ?> loadYaml(String fileName) throws FileNotFoundException
    {
        InputStream in = YamlUtil.class.getClassLoader().getResourceAsStream(fileName);
        return StringUtils.isNotEmpty(fileName) ? (LinkedHashMap<?, ?>) new Yaml().load(in) : null;
    }

    public static void dumpYaml(String fileName, Map<?, ?> map) throws IOException
    {
        if (StringUtils.isNotEmpty(fileName))
        {
            FileWriter fileWriter = new FileWriter(YamlUtil.class.getResource(fileName).getFile());
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            Yaml yaml = new Yaml(options);
            yaml.dump(map, fileWriter);
        }
    }

    public static Object getProperty(Map<?, ?> map, Object qualifiedKey)
    {
        if (map != null && !map.isEmpty() && qualifiedKey != null)
        {
            String input = String.valueOf(qualifiedKey);
            if (!"".equals(input))
            {
                if (input.contains("."))
                {
                    int index = input.indexOf(".");
                    String left = input.substring(0, index);
                    String right = input.substring(index + 1, input.length());
                    return getProperty((Map<?, ?>) map.get(left), right);
                }
                else if (map.containsKey(input))
                {
                    return map.get(input);
                }
                else
                {
                    return null;
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static void setProperty(Map<?, ?> map, Object qualifiedKey, Object value)
    {
        if (map != null && !map.isEmpty() && qualifiedKey != null)
        {
            String input = String.valueOf(qualifiedKey);
            if (!input.equals(""))
            {
                if (input.contains("."))
                {
                    int index = input.indexOf(".");
                    String left = input.substring(0, index);
                    String right = input.substring(index + 1, input.length());
                    setProperty((Map<?, ?>) map.get(left), right, value);
                }
                else
                {
                    ((Map<Object, Object>) map).put(qualifiedKey, value);
                }
            }
        }
    }
}

以下是对这段 Java 代码的逐块分析:

package com.ruoyi.common.utils;

import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import com.ruoyi.common.utils.StringUtils;

这部分代码声明了包名,并导入了必要的类。包括用于处理文件未找到异常的FileNotFoundException、用于写入文件的FileWriter、用于处理输入输出异常的IOException、用于读取输入流的InputStream、用于存储 YAML 数据的LinkedHashMapMap、用于配置 YAML 输出格式的DumperOptions和用于处理 YAML 数据的Yaml,以及可能是自定义的字符串处理工具类StringUtils

/**
 * 配置处理工具类
 * 
 * @author yml
 */
public class YamlUtil {

这是一个名为YamlUtil的公共类的开始,带有一个 JavaDoc 注释,表明这个类是用于处理配置的工具类,作者是 “yml”。

    public static Map<?,?> loadYaml(String fileName) throws FileNotFoundException {
        InputStream in = YamlUtil.class.getClassLoader().getResourceAsStream(fileName);
        return StringUtils.isNotEmpty(fileName)? (LinkedHashMap<?,?>) new Yaml().load(in) : null;
    }

这个静态方法loadYaml用于加载 YAML 文件。

接受一个文件名作为参数。通过YamlUtil.class.getClassLoader().getResourceAsStream(fileName)获取 YAML 文件的输入流。如果文件名不为空,使用new Yaml().load(in)加载 YAML 数据,并将其转换为LinkedHashMap类型后返回;如果文件名为空,则返回null

    public static void dumpYaml(String fileName, Map<?,?> map) throws IOException {
        if (StringUtils.isNotEmpty(fileName)) {
            FileWriter fileWriter = new FileWriter(YamlUtil.class.getResource(fileName).getFile());
            DumperOptions options = new DumperOptions();
            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
            Yaml yaml = new Yaml(options);
            yaml.dump(map, fileWriter);
        }
    }

这个静态方法dumpYaml用于将数据写入 YAML 文件。

接受一个文件名和一个Map对象作为参数。如果文件名不为空,创建一个FileWriter对象用于写入文件。创建DumperOptions对象并设置输出格式为块风格。创建一个Yaml对象并使用设置好的选项。最后使用yaml.dump(map, fileWriter)Map中的数据写入 YAML 文件。

    public static Object getProperty(Map<?,?> map, Object qualifiedKey) {
        if (map!= null &&!map.isEmpty() && qualifiedKey!= null) {
            String input = String.valueOf(qualifiedKey);
            if (!"".equals(input)) {
                if (input.contains(".")) {
                    int index = input.indexOf(".");
                    String left = input.substring(0, index);
                    String right = input.substring(index + 1, input.length());
                    return getProperty((Map<?,?>) map.get(left), right);
                } else if (map.containsKey(input)) {
                    return map.get(input);
                } else {
                    return null;
                }
            }
        }
        return null;
    }

这个静态方法getProperty用于获取 YAML 配置中的属性值。

接受一个Map对象和一个限定键作为参数。如果Map不为空且不为空映射,并且限定键不为空,则进行属性值的获取。将限定键转换为字符串,如果字符串不为空且包含 “.”,则进行递归调用以获取嵌套的属性值;如果不包含 “.” 且Map中包含该键,则返回对应的值;否则返回null

    @SuppressWarnings("unchecked")
    public static void setProperty(Map<?,?> map, Object qualifiedKey, Object value) {
        if (map!= null &&!map.isEmpty() && qualifiedKey!= null) {
            String input = String.valueOf(qualifiedKey);
            if (!input.equals("")) {
                if (input.contains(".")) {
                    int index = input.indexOf(".");
                    String left = input.substring(0, index);
                    String right = input.substring(index + 1, input.length());
                    setProperty((Map<?,?>) map.get(left), right, value);
                } else {
                    ((Map<Object, Object>) map).put(qualifiedKey, value);
                }
            }
        }
    }
}

这个静态方法setProperty用于设置 YAML 配置中的属性值。

接受一个Map对象、一个限定键和一个值作为参数。如果Map不为空且不为空映射,并且限定键不为空,则进行属性值的设置。将限定键转换为字符串,如果字符串不为空且包含 “.”,则进行递归调用以设置嵌套的属性值;如果不包含 “.”,则直接在Map中设置对应的值。使用@SuppressWarnings("unchecked")注解来抑制未经检查的类型转换警告。

以下是对这段 Java 代码的分析:

一、功能概述

这个类YamlUtil是一个用于处理 YAML 配置文件的工具类。它提供了加载 YAML 文件、将数据写入 YAML 文件、获取 YAML 配置中的属性值以及设置属性值的功能。

二、代码详解

  1. 导入依赖

    • import java.io.FileNotFoundException;:用于处理文件未找到的异常。
    • import java.io.FileWriter;:用于将数据写入文件。
    • import java.io.IOException;:用于处理输入输出异常。
    • import java.io.InputStream;:用于读取输入流。
    • import java.util.LinkedHashMap;:用于存储 YAML 数据的映射结构。
    • import java.util.Map;:用于定义方法的参数和返回类型。
    • import org.yaml.snakeyaml.DumperOptions;:用于配置 YAML 输出的格式选项。
    • import org.yaml.snakeyaml.Yaml;:用于处理 YAML 数据的库。
    • import com.ruoyi.common.utils.StringUtils;:可能是自定义的字符串处理工具类。
  2. 方法分析

    • loadYaml(String fileName)

      • 这个方法接受一个文件名作为参数,用于加载 YAML 文件。
      • 通过YamlUtil.class.getClassLoader().getResourceAsStream(fileName)获取 YAML 文件的输入流。
      • 如果文件名不为空,则使用new Yaml().load(in)加载 YAML 数据,并将其转换为LinkedHashMap类型后返回;如果文件名为空,则返回null
    • dumpYaml(String fileName, Map<?,?> map)

      • 这个方法接受一个文件名和一个Map对象作为参数,用于将数据写入 YAML 文件。
      • 如果文件名不为空,创建一个FileWriter对象,用于写入文件。
      • 创建DumperOptions对象,设置输出的格式为块风格(FlowStyle.BLOCK)。
      • 创建一个Yaml对象,并使用设置好的选项。
      • 使用yaml.dump(map, fileWriter)Map中的数据写入 YAML 文件。
    • getProperty(Map<?,?> map, Object qualifiedKey)

      • 这个方法接受一个Map对象和一个限定键作为参数,用于获取 YAML 配置中的属性值。
      • 如果Map不为空且不为空映射,并且限定键不为空,则进行属性值的获取。
      • 将限定键转换为字符串,如果字符串不为空且包含 “.”,则进行递归调用以获取嵌套的属性值;如果不包含 “.” 且Map中包含该键,则返回对应的值;否则返回null
    • setProperty(Map<?,?> map, Object qualifiedKey, Object value)

      • 这个方法接受一个Map对象、一个限定键和一个值作为参数,用于设置 YAML 配置中的属性值。
      • 如果Map不为空且不为空映射,并且限定键不为空,则进行属性值的设置。
      • 将限定键转换为字符串,如果字符串不为空且包含 “.”,则进行递归调用以设置嵌套的属性值;如果不包含 “.”,则直接在Map中设置对应的值。

三、使用场景和注意事项

  • 使用场景:

    • 在应用程序中,可以使用这个工具类来加载、修改和保存 YAML 配置文件。例如,可以在应用程序启动时加载配置文件,在运行过程中修改配置并保存,或者获取特定的配置属性值用于业务逻辑处理。
  • 注意事项:

    • 在使用loadYaml方法时,要确保文件名正确且文件存在于类路径中,否则会抛出FileNotFoundException异常。
    • 在使用dumpYaml方法时,要确保有写入文件的权限,并且文件名正确。
    • 在处理嵌套的属性值时,要注意键的格式和递归调用的正确性。
    • 确保正确处理可能出现的输入输出异常和空指针异常。
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值