继续学习吧,家人们
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;
这部分代码声明了包名,并导入了必要的类。包括用于处理异步任务异常的CancellationException
和ExecutionException
,用于管理线程池的ExecutorService
和Future
,用于指定时间单位的TimeUnit
,以及用于日志记录的Logger
和LoggerFactory
。
/**
* 线程相关工具类.
*
* @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
用于打印线程执行过程中的异常信息。
如果传入的异常对象t
为null
,并且参数r
是一个Future
对象,则尝试从Future
对象中获取异步任务的结果。如果在获取结果过程中出现CancellationException
异常,则将异常对象设置为ce
;如果出现ExecutionException
异常,则获取其原因并设置为异常对象t
;如果出现InterruptedException
异常,则中断当前线程。
如果异常对象t
不为null
,则使用日志对象记录异常信息,包括异常消息和堆栈跟踪。
以下是对这段 Java 代码的分析:
一、功能概述
这个类Threads
是一个线程相关的工具类,提供了一些实用的方法来处理线程的操作,包括线程休眠、停止线程池和打印线程异常信息等功能。
二、代码详解
-
导入依赖和定义日志对象:
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);
:创建一个日志对象,用于记录线程相关的日志信息。
-
方法分析:
-
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)
:- 这个方法用于打印线程执行过程中的异常信息。
- 如果传入的异常对象
t
为null
,并且参数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
是一个工具类,提供了一些高频使用的方法,主要用于获取系统的临时目录、当前项目工作目录和临时下载目录。
二、代码详解
-
类的定义和注释:
public class ToolUtil
:定义了一个名为ToolUtil
的公共类。@version 1.0
和@author: zmr
:这是 JavaDoc 风格的注释,分别表示类的版本号和作者信息。
-
方法分析:
-
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
异常。
二、代码详解
-
导入依赖:
import com.ruoyi.common.exception.base.BaseException;
:导入自定义的异常类,用于在校验不通过时抛出异常。import java.util.Set;
:用于存储校验结果的集合类型。import javax.validation.ConstraintViolation;
:表示违反约束的对象。import javax.validation.Validation;
:用于构建验证器工厂的类。import javax.validation.Validator;
:用于执行对象校验的接口。
-
静态变量和初始化块:
private static Validator validator;
:声明一个静态的Validator
对象,用于执行校验操作。static { validator = Validation.buildDefaultValidatorFactory().getValidator(); }
:在类加载时初始化validator
对象,通过调用Validation.buildDefaultValidatorFactory()
创建一个默认的验证器工厂,然后从工厂中获取一个验证器。
-
方法分析:
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 数据的LinkedHashMap
和Map
、用于配置 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 配置中的属性值以及设置属性值的功能。
二、代码详解
-
导入依赖:
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;
:可能是自定义的字符串处理工具类。
-
方法分析:
-
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
方法时,要确保有写入文件的权限,并且文件名正确。 - 在处理嵌套的属性值时,要注意键的格式和递归调用的正确性。
- 确保正确处理可能出现的输入输出异常和空指针异常。
- 在使用