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