mirror of https://gitee.com/y_project/RuoYi.git
Pre Merge pull request !503 from MagicJson/master
commit
7325e4d895
|
@ -1,15 +1,16 @@
|
|||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.*;
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 时间工具类
|
||||
|
@ -33,6 +34,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
|||
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
|
||||
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
|
||||
|
||||
// 缓存SimpleDateFormat实例的Map,其中每个格式字符串对应一个ThreadLocal<SimpleDateFormat>
|
||||
private static final Map<String, ThreadLocal<SimpleDateFormat>> dateFormatMap = new HashMap<>();
|
||||
/**
|
||||
* 获取当前Date型日期
|
||||
*
|
||||
|
@ -73,11 +76,39 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
|||
return parseDateToStr(YYYY_MM_DD, date);
|
||||
}
|
||||
|
||||
public static final String parseDateToStr(final String format, final Date date)
|
||||
{
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
|
||||
/**
|
||||
* 原代码每次new消耗性能 修改后提升性能并保证线程安全
|
||||
* 将给定日期格式化为指定格式的字符串
|
||||
* @param format 日期格式字符串,例如 "yyyy-MM-dd"
|
||||
* @param date 需要格式化的日期对象
|
||||
* @return 格式化后的日期字符串
|
||||
* @throws IllegalArgumentException 如果格式字符串或日期对象为空时抛出
|
||||
*/
|
||||
public static String parseDateToStr(final String format, final Date date) {
|
||||
if (!StringUtils.hasLength(format)) {
|
||||
throw new IllegalArgumentException("Format must not be null or empty");
|
||||
}
|
||||
if (Objects.isNull(date)) {
|
||||
throw new IllegalArgumentException("Date must not be null");
|
||||
}
|
||||
return getDateFormat(format).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取与指定格式关联的SimpleDateFormat实例
|
||||
* 如果Map中不存在该格式的实例,则创建一个新的实例并存入Map
|
||||
* @param format 日期格式字符串
|
||||
* @return 与指定格式关联的SimpleDateFormat实例
|
||||
*/
|
||||
private static SimpleDateFormat getDateFormat(final String format) {
|
||||
return dateFormatMap
|
||||
.computeIfAbsent(format
|
||||
, k -> ThreadLocal.withInitial(() -> new SimpleDateFormat(k)))
|
||||
.get();
|
||||
}
|
||||
|
||||
|
||||
public static final Date dateTime(final String format, final String ts)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.ruoyi.common.utils.spring;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
@ -8,31 +9,93 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* spring工具类 方便在非spring管理环境中获取bean
|
||||
*
|
||||
*
|
||||
* 该工具类通过实现BeanFactoryPostProcessor和ApplicationContextAware接口,
|
||||
* 在Spring容器初始化时保存ApplicationContext和BeanFactory的引用,以便在非Spring管理的环境中获取bean
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
|
||||
{
|
||||
/** Spring应用上下文环境 */
|
||||
private static ConfigurableListableBeanFactory beanFactory;
|
||||
/** Spring应用上下文环境*/
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
/**
|
||||
* 用于存储ConfigurableListableBeanFactory的AtomicReference
|
||||
*/
|
||||
private static final AtomicReference<Optional<ConfigurableListableBeanFactory>> beanFactoryRef = new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* 用于存储ApplicationContext的AtomicReference
|
||||
*/
|
||||
private static final AtomicReference<Optional<ApplicationContext>> applicationContextRef = new AtomicReference<>();
|
||||
|
||||
private static final String UNINITIALIZED_EXCEPTION = " is not initialized yet.";
|
||||
|
||||
private SpringUtils(){}
|
||||
|
||||
/**
|
||||
* 在BeanFactory后处理器中设置beanFactory引用
|
||||
*
|
||||
* @param beanFactory ConfigurableListableBeanFactory实例
|
||||
* @throws BeansException 如果beanFactory设置过程中出现异常
|
||||
*/
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
|
||||
{
|
||||
SpringUtils.beanFactory = beanFactory;
|
||||
beanFactoryRef.set(Optional.of(beanFactory));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置ApplicationContext引用
|
||||
*
|
||||
* @param applicationContext ApplicationContext实例
|
||||
* @throws BeansException 如果applicationContext设置过程中出现异常
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
SpringUtils.applicationContext = applicationContext;
|
||||
applicationContextRef.set(Optional.of(applicationContext));
|
||||
}
|
||||
|
||||
/**
|
||||
* 该方法接受一个参数,并返回一个异常 Supplier
|
||||
*
|
||||
* @param clz 异常所属类
|
||||
* @param suffix 异常信息后缀
|
||||
* @return 返回RuntimeException的Supplier
|
||||
*/
|
||||
private static Supplier<RuntimeException> exceptionSupplier(Class<?> clz, String suffix) {
|
||||
return () -> new IllegalStateException(generateErrorMessage(clz, suffix));
|
||||
}
|
||||
|
||||
/**
|
||||
* 该方法接受一个参数,并返回一个异常 Supplier
|
||||
*
|
||||
* @param clz 异常所属类
|
||||
* @param suffix 异常信息后缀
|
||||
* @return 返回拼接好的异常信息 类名+异常信息后缀
|
||||
*/
|
||||
private static String generateErrorMessage(Class<?> clz,String suffix) {
|
||||
Function<String, String> errorMessageFunction = errorMessageGenerator(suffix);
|
||||
return errorMessageFunction.apply(clz.getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 该方法接受一个参数,返回拼接功能的Function
|
||||
*
|
||||
* @param suffix 异常信息后缀
|
||||
* @return 返回拼接功能的Function
|
||||
*/
|
||||
private static Function<String, String> errorMessageGenerator(String suffix) {
|
||||
return parameter -> parameter + suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,7 +109,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getBean(String name) throws BeansException
|
||||
{
|
||||
return (T) beanFactory.getBean(name);
|
||||
return (T) beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class, UNINITIALIZED_EXCEPTION))
|
||||
.getBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,8 +124,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static <T> T getBean(Class<T> clz) throws BeansException
|
||||
{
|
||||
T result = (T) beanFactory.getBean(clz);
|
||||
return result;
|
||||
return beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class, UNINITIALIZED_EXCEPTION))
|
||||
.getBean(clz);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +137,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static boolean containsBean(String name)
|
||||
{
|
||||
return beanFactory.containsBean(name);
|
||||
return beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
|
||||
.containsBean(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,7 +152,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.isSingleton(name);
|
||||
return beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
|
||||
.isSingleton(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,7 +165,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.getType(name);
|
||||
return beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
|
||||
.getType(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,12 +180,14 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
|
||||
{
|
||||
return beanFactory.getAliases(name);
|
||||
return beanFactoryRef.get()
|
||||
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
|
||||
.getAliases(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取aop代理对象
|
||||
*
|
||||
*
|
||||
* @param invoker
|
||||
* @return
|
||||
*/
|
||||
|
@ -130,7 +204,11 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static String[] getActiveProfiles()
|
||||
{
|
||||
return applicationContext.getEnvironment().getActiveProfiles();
|
||||
return applicationContextRef
|
||||
.get()
|
||||
.orElseThrow(exceptionSupplier(ApplicationContext.class, UNINITIALIZED_EXCEPTION))
|
||||
.getEnvironment()
|
||||
.getActiveProfiles();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,7 +231,11 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
|
|||
*/
|
||||
public static String getRequiredProperty(String key)
|
||||
{
|
||||
return applicationContext.getEnvironment().getRequiredProperty(key);
|
||||
return applicationContextRef
|
||||
.get()
|
||||
.orElseThrow(exceptionSupplier(ApplicationContext.class, UNINITIALIZED_EXCEPTION))
|
||||
.getEnvironment()
|
||||
.getRequiredProperty(key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.ruoyi.framework.aspectj;
|
||||
|
||||
import java.util.Objects;
|
||||
import com.ruoyi.common.annotation.DataSource;
|
||||
import com.ruoyi.common.config.datasource.DynamicDataSourceContextHolder;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
|
@ -11,9 +12,8 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.common.annotation.DataSource;
|
||||
import com.ruoyi.common.config.datasource.DynamicDataSourceContextHolder;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 多数据源处理
|
||||
|
@ -34,24 +34,27 @@ public class DataSourceAspect
|
|||
|
||||
}
|
||||
|
||||
// 增加错误捕捉与日志记录
|
||||
@Around("dsPointCut()")
|
||||
public Object around(ProceedingJoinPoint point) throws Throwable
|
||||
{
|
||||
DataSource dataSource = getDataSource(point);
|
||||
|
||||
if (StringUtils.isNotNull(dataSource))
|
||||
if (Objects.nonNull(dataSource))
|
||||
{
|
||||
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
return point.proceed();
|
||||
}
|
||||
finally
|
||||
{
|
||||
// 销毁数据源 在执行方法之后
|
||||
} catch (Throwable throwable) {
|
||||
logger.error("Error during data source switch: {}", throwable.getMessage());
|
||||
throw throwable;
|
||||
} finally {
|
||||
DynamicDataSourceContextHolder.clearDataSourceType();
|
||||
if(logger.isInfoEnabled()){
|
||||
logger.info("Cleared data source setting after method execution");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue