Skip to content

Commit 2fc99ee

Browse files
committed
feat: 添加 Spring 工具类,SpringUtil
1 parent ede57a9 commit 2fc99ee

3 files changed

Lines changed: 190 additions & 20 deletions

File tree

common/core/src/main/java/top/cadecode/uniboot/common/core/enums/CommonErrorEnum.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@
1212
@Getter
1313
public enum CommonErrorEnum implements UniErrorCode {
1414

15+
// 工具类
1516
// json
1617
CAST_BEAN_TO_JSON_FAIL(0, "cast bean to json fail"),
17-
CAST_JSON_TO_BEAN_FAIL(0, "cast json to bean fail"),
18+
CAST_JSON_TO_BEAN_FAIL(1, "cast json to bean fail"),
19+
// spring
20+
NO_LISTABLE_BEAN_FACTORY(2, "no ConfigurableListableBeanFactory "),
21+
CAN_NOT_UNREGISTER_BEAN(3, "can not unregister bean"),
1822
;
1923

2024
private final String code;
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package top.cadecode.uniboot.common.core.util;
2+
3+
import cn.hutool.core.util.ArrayUtil;
4+
import com.fasterxml.jackson.core.type.TypeReference;
5+
import org.springframework.beans.BeansException;
6+
import org.springframework.beans.factory.ListableBeanFactory;
7+
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
8+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
9+
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
10+
import org.springframework.context.ApplicationContext;
11+
import org.springframework.context.ApplicationContextAware;
12+
import org.springframework.context.ConfigurableApplicationContext;
13+
import org.springframework.core.ResolvableType;
14+
import org.springframework.stereotype.Component;
15+
import top.cadecode.uniboot.common.core.enums.CommonErrorEnum;
16+
import top.cadecode.uniboot.common.core.exception.UniException;
17+
18+
import java.lang.reflect.ParameterizedType;
19+
import java.util.Arrays;
20+
import java.util.Map;
21+
22+
/**
23+
* Spring IOC 容器工具
24+
*
25+
* @author Cade Li
26+
* @since 2023/6/9
27+
*/
28+
@Component
29+
public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextAware {
30+
31+
/**
32+
* 使用 @PostConstruct 时,ApplicationContext 还未加载,导致空指针
33+
* 注入 ConfigurableListableBeanFactory 操作 bean
34+
*/
35+
private static ConfigurableListableBeanFactory BEAN_FACTORY;
36+
private static ApplicationContext APPLICATION_CONTEXT;
37+
38+
public static ApplicationContext getApplicationContext() {
39+
return APPLICATION_CONTEXT;
40+
}
41+
42+
public static ListableBeanFactory getBeanFactory() {
43+
return null == BEAN_FACTORY ? APPLICATION_CONTEXT : BEAN_FACTORY;
44+
}
45+
46+
public static ConfigurableListableBeanFactory getConfigurableBeanFactory() {
47+
final ConfigurableListableBeanFactory factory;
48+
if (null != BEAN_FACTORY) {
49+
factory = BEAN_FACTORY;
50+
} else if (APPLICATION_CONTEXT instanceof ConfigurableApplicationContext) {
51+
factory = ((ConfigurableApplicationContext) APPLICATION_CONTEXT).getBeanFactory();
52+
} else {
53+
throw UniException.of(CommonErrorEnum.NO_LISTABLE_BEAN_FACTORY, "");
54+
}
55+
return factory;
56+
}
57+
58+
/**
59+
* 通过name获取 Bean
60+
*/
61+
@SuppressWarnings("unchecked")
62+
public static <T> T getBean(String name) {
63+
return (T) getBeanFactory().getBean(name);
64+
}
65+
66+
/**
67+
* 通过class获取Bean
68+
*/
69+
public static <T> T getBean(Class<T> clazz) {
70+
return getBeanFactory().getBean(clazz);
71+
}
72+
73+
/**
74+
* 通过name,以及Clazz返回指定的Bean
75+
*/
76+
public static <T> T getBean(String name, Class<T> clazz) {
77+
return getBeanFactory().getBean(name, clazz);
78+
}
79+
80+
/**
81+
* 通过类型参考返回带泛型参数的Bean
82+
*/
83+
@SuppressWarnings("unchecked")
84+
public static <T> T getBean(TypeReference<T> reference) {
85+
final ParameterizedType parameterizedType = (ParameterizedType) reference.getType();
86+
final Class<T> rawType = (Class<T>) parameterizedType.getRawType();
87+
final Class<?>[] genericTypes = Arrays.stream(parameterizedType.getActualTypeArguments()).map(type -> (Class<?>) type).toArray(Class[]::new);
88+
final String[] beanNames = getBeanFactory().getBeanNamesForType(ResolvableType.forClassWithGenerics(rawType, genericTypes));
89+
return getBean(beanNames[0], rawType);
90+
}
91+
92+
/**
93+
* 获取指定类型对应的所有Bean,包括子类
94+
*/
95+
public static <T> Map<String, T> getBeansOfType(Class<T> type) {
96+
return getBeanFactory().getBeansOfType(type);
97+
}
98+
99+
/**
100+
* 获取指定类型对应的Bean名称,包括子类
101+
*/
102+
public static String[] getBeanNamesForType(Class<?> type) {
103+
return getBeanFactory().getBeanNamesForType(type);
104+
}
105+
106+
/**
107+
* 获取配置文件配置项的值
108+
*/
109+
public static String getProperty(String key) {
110+
if (null == APPLICATION_CONTEXT) {
111+
return null;
112+
}
113+
return APPLICATION_CONTEXT.getEnvironment().getProperty(key);
114+
}
115+
116+
/**
117+
* 获取应用程序名称
118+
*/
119+
public static String getApplicationName() {
120+
return getProperty("spring.application.name");
121+
}
122+
123+
/**
124+
* 获取当前的环境配置,无配置返回null
125+
*/
126+
public static String[] getActiveProfiles() {
127+
if (null == APPLICATION_CONTEXT) {
128+
return null;
129+
}
130+
return APPLICATION_CONTEXT.getEnvironment().getActiveProfiles();
131+
}
132+
133+
/**
134+
* 获取当前的环境配置,当有多个环境配置时,只获取第一个
135+
*/
136+
public static String getActiveProfile() {
137+
final String[] activeProfiles = getActiveProfiles();
138+
return ArrayUtil.isNotEmpty(activeProfiles) ? activeProfiles[0] : null;
139+
}
140+
141+
/**
142+
* 动态向Spring注册Bean
143+
*/
144+
public static <T> void registerBean(String beanName, T bean) {
145+
final ConfigurableListableBeanFactory factory = getConfigurableBeanFactory();
146+
factory.autowireBean(bean);
147+
factory.registerSingleton(beanName, bean);
148+
}
149+
150+
/**
151+
* 注销 bean
152+
*/
153+
public static void unregisterBean(String beanName) {
154+
final ConfigurableListableBeanFactory factory = getConfigurableBeanFactory();
155+
if (factory instanceof DefaultSingletonBeanRegistry) {
156+
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) factory;
157+
registry.destroySingleton(beanName);
158+
} else {
159+
throw UniException.of(CommonErrorEnum.CAN_NOT_UNREGISTER_BEAN, "");
160+
}
161+
}
162+
163+
/**
164+
* 发布事件
165+
*/
166+
public static void publishEvent(Object event) {
167+
if (null != APPLICATION_CONTEXT) {
168+
APPLICATION_CONTEXT.publishEvent(event);
169+
}
170+
}
171+
172+
@Override
173+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
174+
BEAN_FACTORY = beanFactory;
175+
}
176+
177+
@Override
178+
public void setApplicationContext(ApplicationContext applicationContext) {
179+
APPLICATION_CONTEXT = applicationContext;
180+
}
181+
}

common/plugin/swagger/src/main/java/top/cadecode/uniboot/common/plugin/swagger/util/SwaggerRegisterKit.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
import cn.hutool.core.util.ObjectUtil;
44
import lombok.RequiredArgsConstructor;
55
import lombok.extern.slf4j.Slf4j;
6-
import org.springframework.beans.BeansException;
7-
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
8-
import org.springframework.context.ApplicationContext;
9-
import org.springframework.context.ApplicationContextAware;
10-
import org.springframework.context.ConfigurableApplicationContext;
116
import springfox.documentation.builders.ApiInfoBuilder;
127
import springfox.documentation.builders.RequestHandlerSelectors;
138
import springfox.documentation.service.ApiInfo;
149
import springfox.documentation.service.Contact;
1510
import springfox.documentation.spi.DocumentationType;
1611
import springfox.documentation.spring.web.plugins.Docket;
12+
import top.cadecode.uniboot.common.core.util.SpringUtil;
1713
import top.cadecode.uniboot.common.plugin.swagger.config.SwaggerProperties;
1814

1915
/**
@@ -24,28 +20,17 @@
2420
*/
2521
@Slf4j
2622
@RequiredArgsConstructor
27-
public class SwaggerRegisterKit implements ApplicationContextAware {
28-
29-
private ConfigurableApplicationContext applicationContext;
30-
31-
@Override
32-
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
33-
if (applicationContext instanceof ConfigurableApplicationContext) {
34-
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
35-
}
36-
}
23+
public class SwaggerRegisterKit {
3724

3825
/**
3926
* 配置 Swagger Docket
4027
*/
4128
public void registerModule(SwaggerProperties prop) {
4229
log.info("Starting to config swagger dockets");
43-
if (ObjectUtil.isEmpty(prop.getModule()) || ObjectUtil.isEmpty(applicationContext)) {
30+
if (ObjectUtil.isEmpty(prop.getModule())) {
4431
log.info("Swagger dockets config not found");
4532
return;
4633
}
47-
// 获取 BeanFactory,动态注册 Docket
48-
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
4934
prop.getModule().forEach((group, packageName) -> {
5035
Docket docket = new Docket(DocumentationType.SWAGGER_2)
5136
// 设置文档信息
@@ -56,7 +41,7 @@ public void registerModule(SwaggerProperties prop) {
5641
.build()
5742
// 设置分组名称
5843
.groupName(group);
59-
beanFactory.registerSingleton(group + "Docket", docket);
44+
SpringUtil.registerBean(group + "Docket", docket);
6045
});
6146
log.info("Configuring swagger dockets ok");
6247
}

0 commit comments

Comments
 (0)