修改代码保证上下文对象线程安全且避免BeanFactory、Context可能未初始化完全时使用导致报错 为SpringUtils使用Spring上下文提供更安全的使用

pull/503/head
MagicJson 2024-07-11 00:01:12 +08:00
parent 7c8278fce6
commit de1aa82d91
1 changed files with 99 additions and 17 deletions

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.utils.spring; package com.ruoyi.common.utils.spring;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.aop.framework.AopContext; import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; 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.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component; 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 便springbean * spring 便springbean
* *
* BeanFactoryPostProcessorApplicationContextAware
* SpringApplicationContextBeanFactory便Springbean
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
{ {
/** Spring应用上下文环境 */ /** Spring应用上下文环境*/
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext; /**
* ConfigurableListableBeanFactoryAtomicReference
*/
private static final AtomicReference<Optional<ConfigurableListableBeanFactory>> beanFactoryRef = new AtomicReference<>();
/**
* ApplicationContextAtomicReference
*/
private static final AtomicReference<Optional<ApplicationContext>> applicationContextRef = new AtomicReference<>();
private static final String UNINITIALIZED_EXCEPTION = " is not initialized yet.";
private SpringUtils(){}
/**
* BeanFactorybeanFactory
*
* @param beanFactory ConfigurableListableBeanFactory
* @throws BeansException beanFactory
*/
@Override @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{ {
SpringUtils.beanFactory = beanFactory; beanFactoryRef.set(Optional.of(beanFactory));
} }
/**
* ApplicationContext
*
* @param applicationContext ApplicationContext
* @throws BeansException applicationContext
*/
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{ {
SpringUtils.applicationContext = applicationContext; applicationContextRef.set(Optional.of(applicationContext));
}
/**
* Supplier
*
* @param clz
* @param suffix
* @return RuntimeExceptionSupplier
*/
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") @SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException 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 public static <T> T getBean(Class<T> clz) throws BeansException
{ {
T result = (T) beanFactory.getBean(clz); return beanFactoryRef.get()
return result; .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) 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 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 public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{ {
return beanFactory.getType(name); return beanFactoryRef.get()
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
.getType(name);
} }
/** /**
@ -108,7 +180,9 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
*/ */
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{ {
return beanFactory.getAliases(name); return beanFactoryRef.get()
.orElseThrow(exceptionSupplier(ConfigurableListableBeanFactory.class,UNINITIALIZED_EXCEPTION))
.getAliases(name);
} }
/** /**
@ -130,7 +204,11 @@ public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationC
*/ */
public static String[] getActiveProfiles() 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) public static String getRequiredProperty(String key)
{ {
return applicationContext.getEnvironment().getRequiredProperty(key); return applicationContextRef
.get()
.orElseThrow(exceptionSupplier(ApplicationContext.class, UNINITIALIZED_EXCEPTION))
.getEnvironment()
.getRequiredProperty(key);
} }
} }