feat: 彻底解耦reflections
This commit is contained in:
parent
274febda39
commit
7fcd7c6e02
@ -13,7 +13,11 @@ import org.springframework.util.CollectionUtils;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.*;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 内部的包扫描器,提供特定注解扫描
|
* 内部的包扫描器,提供特定注解扫描
|
||||||
@ -61,6 +65,13 @@ public class ClassPathResourceScanner extends ClassPathScanningCandidateComponen
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析具体类型
|
||||||
|
*
|
||||||
|
* @param bf bean定义
|
||||||
|
* @param cl 类加载器
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
private Class<?> resolveType(BeanDefinition bf, ClassLoader cl) {
|
private Class<?> resolveType(BeanDefinition bf, ClassLoader cl) {
|
||||||
if (null != bf.getBeanClassName()) {
|
if (null != bf.getBeanClassName()) {
|
||||||
try {
|
try {
|
||||||
@ -78,23 +89,19 @@ public class ClassPathResourceScanner extends ClassPathScanningCandidateComponen
|
|||||||
* @param packageNames 包名
|
* @param packageNames 包名
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public Set<Class<?>> scan(Collection<String> packageNames) {
|
public Stream<Class<?>> scan(Collection<String> packageNames) {
|
||||||
// 获取扫描器的ClassLoader,保证同源
|
// 获取扫描器的ClassLoader,保证同源
|
||||||
ClassLoader cl = this.getClass().getClassLoader();
|
ClassLoader cl = this.getClass().getClassLoader();
|
||||||
Set<Class<?>> scanned = new HashSet<>();
|
Stream<Class<?>> stream = packageNames.stream()
|
||||||
for (String packageName : packageNames) {
|
.flatMap(packageName -> {
|
||||||
Set<BeanDefinition> bfs = findCandidateComponents(packageName);
|
Set<BeanDefinition> bfs = findCandidateComponents(packageName);
|
||||||
// 不存在,不要浪费性能
|
// 不存在,不要浪费性能
|
||||||
if (CollectionUtils.isEmpty(bfs)) continue;
|
if (CollectionUtils.isEmpty(bfs)) return Stream.empty();
|
||||||
// 代理并生成子类,并注册到ioc容器
|
// 代理并生成子类,并注册到ioc容器
|
||||||
for (BeanDefinition bf : bfs) {
|
return bfs.stream().map(bf -> resolveType(bf, cl)).filter(Objects::nonNull);
|
||||||
Class<?> resolved = resolveType(bf, cl);
|
});
|
||||||
if (null != resolved) {
|
// 额外返回,以保证类型正确
|
||||||
scanned.add(resolved);
|
return stream.distinct();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scanned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,7 +110,7 @@ public class ClassPathResourceScanner extends ClassPathScanningCandidateComponen
|
|||||||
* @param packageNames 包名
|
* @param packageNames 包名
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public Set<Class<?>> scan(String... packageNames) {
|
public Stream<Class<?>> scan(String... packageNames) {
|
||||||
return scan(Arrays.asList(packageNames));
|
return scan(Arrays.asList(packageNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,9 +25,10 @@ public class EnumConfig implements InitializingBean, ImportBeanDefinitionRegistr
|
|||||||
|
|
||||||
public EnumConfig() {
|
public EnumConfig() {
|
||||||
// 得到枚举类
|
// 得到枚举类
|
||||||
Set<Class<?>> classSet = ClassPathResourceScanner.forSuperType(NamedEnum.class).scan("com.flyfish.project");
|
ClassPathResourceScanner.forSuperType(NamedEnum.class)
|
||||||
// 注入
|
.scan("com.flyfish.project")
|
||||||
classSet.stream().filter(clazz -> ClassUtils.isAssignable(clazz, Enum.class)).forEach(clazz -> {
|
.filter(clazz -> ClassUtils.isAssignable(clazz, Enum.class))
|
||||||
|
.forEach(clazz -> {
|
||||||
String name = StringFormats.camel2Line(clazz.getSimpleName());
|
String name = StringFormats.camel2Line(clazz.getSimpleName());
|
||||||
List<EnumValue> values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> {
|
List<EnumValue> values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> {
|
||||||
result.add(new EnumValue(((Enum<?>) item).name(), ((NamedEnum) item).getName()));
|
result.add(new EnumValue(((Enum<?>) item).name(), ((NamedEnum) item).getName()));
|
||||||
|
@ -34,9 +34,5 @@
|
|||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.reflections</groupId>
|
|
||||||
<artifactId>reflections</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -4,29 +4,25 @@ import com.flyfish.framework.annotations.DictValue;
|
|||||||
import com.flyfish.framework.dict.domain.Dictionary;
|
import com.flyfish.framework.dict.domain.Dictionary;
|
||||||
import com.flyfish.framework.dict.domain.DictionaryValue;
|
import com.flyfish.framework.dict.domain.DictionaryValue;
|
||||||
import com.flyfish.framework.dict.service.DictionaryService;
|
import com.flyfish.framework.dict.service.DictionaryService;
|
||||||
|
import com.flyfish.framework.domain.base.Domain;
|
||||||
import com.flyfish.framework.enums.BlankEnum;
|
import com.flyfish.framework.enums.BlankEnum;
|
||||||
import com.flyfish.framework.enums.NamedEnum;
|
import com.flyfish.framework.enums.NamedEnum;
|
||||||
import com.flyfish.framework.utils.Assert;
|
import com.flyfish.framework.utils.Assert;
|
||||||
|
import com.flyfish.framework.utils.ClassPathResourceScanner;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.reflections.Reflections;
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||||
import org.reflections.scanners.Scanners;
|
|
||||||
import org.reflections.util.ClasspathHelper;
|
|
||||||
import org.reflections.util.ConfigurationBuilder;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典处理器
|
* 字典处理器
|
||||||
@ -45,17 +41,14 @@ public class DictionaryProcessor implements InitializingBean {
|
|||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
String[] basePackages = DictionaryConfig.basePackages();
|
String[] basePackages = DictionaryConfig.basePackages();
|
||||||
Assert.notNull(basePackages, "未指定明确的字典扫描路径!");
|
Assert.notNull(basePackages, "未指定明确的字典扫描路径!");
|
||||||
Collection<URL> urls = Arrays.stream(basePackages).flatMap(pack -> ClasspathHelper.forPackage(pack).stream())
|
Stream<DictValue> annotations = ClassPathResourceScanner.forSuperType(Domain.class)
|
||||||
.collect(Collectors.toList());
|
.scan(basePackages)
|
||||||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
.flatMap(clazz -> Arrays.stream(FieldUtils.getFieldsWithAnnotation(clazz, DictValue.class)))
|
||||||
.setUrls(urls)
|
|
||||||
.setScanners(Scanners.FieldsAnnotated));
|
|
||||||
Set<Field> fields = reflections.getFieldsAnnotatedWith(DictValue.class);
|
|
||||||
if (CollectionUtils.isNotEmpty(fields)) {
|
|
||||||
Flux.fromIterable(fields)
|
|
||||||
.map(field -> field.getAnnotation(DictValue.class))
|
.map(field -> field.getAnnotation(DictValue.class))
|
||||||
.filter(annotation -> null != annotation && StringUtils.isNotBlank(annotation.value()) &&
|
.filter(annotation -> null != annotation && StringUtils.isNotBlank(annotation.value()) &&
|
||||||
BlankEnum.class != annotation.enumType())
|
BlankEnum.class != annotation.enumType());
|
||||||
|
// 查找并更新
|
||||||
|
Flux.fromStream(annotations)
|
||||||
.distinct(DictValue::enumType)
|
.distinct(DictValue::enumType)
|
||||||
// 查找是否存在,不存在插入,存在无视
|
// 查找是否存在,不存在插入,存在无视
|
||||||
.flatMap(annotation -> dictionaryService
|
.flatMap(annotation -> dictionaryService
|
||||||
@ -67,7 +60,6 @@ public class DictionaryProcessor implements InitializingBean {
|
|||||||
.flatMapMany(dictionaryService::updateBatch)
|
.flatMapMany(dictionaryService::updateBatch)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给字典属性赋值
|
* 给字典属性赋值
|
||||||
|
@ -132,24 +132,18 @@ public class WebSecurityConfig {
|
|||||||
ReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService);
|
ReactiveAuthenticationManager authenticationManager = new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService);
|
||||||
return http
|
return http
|
||||||
.securityContextRepository(contextRepository())
|
.securityContextRepository(contextRepository())
|
||||||
.authorizeExchange()
|
.authorizeExchange(spec -> spec.pathMatchers(ArrayUtils.addAll(properties.getAllowUris(), "/api/logout", "/api/login")).permitAll()
|
||||||
.pathMatchers(ArrayUtils.addAll(properties.getAllowUris(), "/api/logout", "/api/login")).permitAll()
|
|
||||||
.pathMatchers("/api/users/**").authenticated()
|
.pathMatchers("/api/users/**").authenticated()
|
||||||
.anyExchange().authenticated()
|
.anyExchange().authenticated())
|
||||||
.and()
|
.formLogin(spec -> spec.disable()) // 配置登录节点
|
||||||
.formLogin() // 配置登录节点
|
.httpBasic(spec -> spec.disable())
|
||||||
.disable()
|
.logout(spec -> spec
|
||||||
.httpBasic()
|
|
||||||
.disable()
|
|
||||||
.logout()
|
|
||||||
.logoutUrl("/api/logout")
|
.logoutUrl("/api/logout")
|
||||||
.logoutSuccessHandler(new JsonLogoutSuccessHandler(authenticationAuditor, tokenProvider))
|
.logoutSuccessHandler(new JsonLogoutSuccessHandler(authenticationAuditor, tokenProvider)))
|
||||||
.and()
|
.exceptionHandling(spec -> spec
|
||||||
.exceptionHandling()
|
|
||||||
.authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
|
.authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
|
||||||
.accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.UNAUTHORIZED))
|
.accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.UNAUTHORIZED)))
|
||||||
.and()
|
.csrf(spec -> spec.disable())
|
||||||
.csrf().disable()
|
|
||||||
.addFilterAt(
|
.addFilterAt(
|
||||||
configure(authenticationManager, authenticationAuditor, authenticationConverter),
|
configure(authenticationManager, authenticationAuditor, authenticationConverter),
|
||||||
SecurityWebFiltersOrder.FORM_LOGIN)
|
SecurityWebFiltersOrder.FORM_LOGIN)
|
||||||
|
@ -84,7 +84,7 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
|
|||||||
// 寻找基本包路径
|
// 寻找基本包路径
|
||||||
String basePackage = basePackages.stream().findFirst().orElse("com.flyfish.project");
|
String basePackage = basePackages.stream().findFirst().orElse("com.flyfish.project");
|
||||||
// 获取被注解的类,开始编译
|
// 获取被注解的类,开始编译
|
||||||
Set<Class<?>> classes = ClassPathResourceScanner.forAnnotation(RestBean.class).scan(basePackages);
|
Stream<Class<?>> classes = ClassPathResourceScanner.forAnnotation(RestBean.class).scan(basePackages);
|
||||||
// 并发编译,快速接入,准备注册的repo
|
// 并发编译,快速接入,准备注册的repo
|
||||||
Map<RestBeanCandidate, List<String>> compiledClasses = compile(basePackage, classes);
|
Map<RestBeanCandidate, List<String>> compiledClasses = compile(basePackage, classes);
|
||||||
// 从repo开始,注册bean
|
// 从repo开始,注册bean
|
||||||
@ -110,7 +110,7 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res
|
|||||||
* @param classes 类集合
|
* @param classes 类集合
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
private Map<RestBeanCandidate, List<String>> compile(String basePackage, Set<Class<?>> classes) {
|
private Map<RestBeanCandidate, List<String>> compile(String basePackage, Stream<Class<?>> classes) {
|
||||||
Map<RestBeanCandidate, List<String>> compiled = new ConcurrentHashMap<>();
|
Map<RestBeanCandidate, List<String>> compiled = new ConcurrentHashMap<>();
|
||||||
classes.forEach(clazz -> {
|
classes.forEach(clazz -> {
|
||||||
RestBean restBean = clazz.getDeclaredAnnotation(RestBean.class);
|
RestBean restBean = clazz.getDeclaredAnnotation(RestBean.class);
|
||||||
|
@ -8,12 +8,11 @@ import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
|||||||
public class JacksonRedisSerializerFactory {
|
public class JacksonRedisSerializerFactory {
|
||||||
|
|
||||||
public static Jackson2JsonRedisSerializer<Object> produce() {
|
public static Jackson2JsonRedisSerializer<Object> produce() {
|
||||||
// 设置序列化
|
// 构造object mapper
|
||||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
|
|
||||||
ObjectMapper om = new ObjectMapper();
|
ObjectMapper om = new ObjectMapper();
|
||||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||||
jackson2JsonRedisSerializer.setObjectMapper(om);
|
// 设置序列化
|
||||||
return jackson2JsonRedisSerializer;
|
return new Jackson2JsonRedisSerializer<Object>(om, Object.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,11 @@ public class EnumController {
|
|||||||
private final Map<String, List<EnumValue>> values = new HashMap<>();
|
private final Map<String, List<EnumValue>> values = new HashMap<>();
|
||||||
|
|
||||||
public EnumController() {
|
public EnumController() {
|
||||||
Set<Class<?>> classSet = ClassPathResourceScanner.forSuperType(NamedEnum.class).scan("com.flyfish.project", "com.flyfish.framework");
|
|
||||||
// 注入
|
// 注入
|
||||||
classSet.stream().filter(clazz -> ClassUtils.isAssignable(clazz, Enum.class)).forEach(clazz -> {
|
ClassPathResourceScanner.forSuperType(NamedEnum.class)
|
||||||
|
.scan("com.flyfish.project", "com.flyfish.framework")
|
||||||
|
.filter(clazz -> ClassUtils.isAssignable(clazz, Enum.class))
|
||||||
|
.forEach(clazz -> {
|
||||||
String name = StringFormats.camel2Line(ClassUtils.getShortClassName(clazz));
|
String name = StringFormats.camel2Line(ClassUtils.getShortClassName(clazz));
|
||||||
List<EnumValue> values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> {
|
List<EnumValue> values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> {
|
||||||
result.add(new EnumValue(((Enum<?>) item).name(), ((NamedEnum) item).getName()));
|
result.add(new EnumValue(((Enum<?>) item).name(), ((NamedEnum) item).getName()));
|
||||||
|
6
pom.xml
6
pom.xml
@ -25,7 +25,6 @@
|
|||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<jasypt.version>3.1.0</jasypt.version>
|
<jasypt.version>3.1.0</jasypt.version>
|
||||||
<jjwt.version>0.12.6</jjwt.version>
|
<jjwt.version>0.12.6</jjwt.version>
|
||||||
<reflection.version>0.10.2</reflection.version>
|
|
||||||
<r2dbc-mysql.version>1.1.3</r2dbc-mysql.version>
|
<r2dbc-mysql.version>1.1.3</r2dbc-mysql.version>
|
||||||
<flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
|
||||||
<captcha.version>1.3.0</captcha.version>
|
<captcha.version>1.3.0</captcha.version>
|
||||||
@ -112,11 +111,6 @@
|
|||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.16.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.reflections</groupId>
|
|
||||||
<artifactId>reflections</artifactId>
|
|
||||||
<version>${reflection.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.springboot.plugin</groupId>
|
<groupId>io.springboot.plugin</groupId>
|
||||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user