diff --git a/flyfish-common/pom.xml b/flyfish-common/pom.xml index 79da011..0d26753 100644 --- a/flyfish-common/pom.xml +++ b/flyfish-common/pom.xml @@ -59,10 +59,6 @@ org.slf4j slf4j-api - - org.reflections - reflections - diff --git a/flyfish-common/src/main/java/com/flyfish/framework/utils/ClassPathResourceScanner.java b/flyfish-common/src/main/java/com/flyfish/framework/utils/ClassPathResourceScanner.java new file mode 100644 index 0000000..d6ceb36 --- /dev/null +++ b/flyfish-common/src/main/java/com/flyfish/framework/utils/ClassPathResourceScanner.java @@ -0,0 +1,109 @@ +package com.flyfish.framework.utils; + +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.core.type.classreading.MetadataReader; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.core.type.filter.AssignableTypeFilter; +import org.springframework.core.type.filter.TypeFilter; +import org.springframework.lang.NonNull; +import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.*; + +/** + * 内部的包扫描器,提供特定注解扫描 + * + * @author wangyu + */ +public class ClassPathResourceScanner extends ClassPathScanningCandidateComponentProvider { + + private final TypeFilter filter; + + /** + * 扫描某个特定注解 + * + * @param annoType 注解类型 + * @return 结果 + */ + public static ClassPathResourceScanner forAnnotation(Class annoType) { + return new ClassPathResourceScanner(new AnnotationTypeFilter(annoType)); + } + + /** + * 扫描子类 + * + * @param superType 父类型 + * @return 结果 + */ + public static ClassPathResourceScanner forSuperType(Class superType) { + return new ClassPathResourceScanner(new AssignableTypeFilter(superType)); + } + + private ClassPathResourceScanner(TypeFilter filter) { + super(false); + this.filter = filter; + resetFilters(false); + addIncludeFilter(filter); + } + + @Override + protected boolean isCandidateComponent(@NonNull MetadataReader metadataReader) throws IOException { + return filter.match(metadataReader, getMetadataReaderFactory()); + } + + @Override + protected boolean isCandidateComponent(@NonNull AnnotatedBeanDefinition beanDefinition) { + return true; + } + + private Class resolveType(BeanDefinition bf, ClassLoader cl) { + if (null != bf.getBeanClassName()) { + try { + return ClassUtils.forName(bf.getBeanClassName(), cl); + } catch (ClassNotFoundException e) { + return null; + } + } + return null; + } + + /** + * 扫描类 + * + * @param packageNames 包名 + * @return 结果 + */ + public Set> scan(Collection packageNames) { + // 获取扫描器的ClassLoader,保证同源 + ClassLoader cl = this.getClass().getClassLoader(); + Set> scanned = new HashSet<>(); + for (String packageName : packageNames) { + Set 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; + } + + /** + * 扫描类 + * + * @param packageNames 包名 + * @return 结果 + */ + public Set> scan(String... packageNames) { + return scan(Arrays.asList(packageNames)); + } +} \ No newline at end of file diff --git a/flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java b/flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java index 2a4cb2b..ac45f9c 100644 --- a/flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java +++ b/flyfish-data/src/main/java/com/flyfish/framework/config/EnumConfig.java @@ -2,9 +2,9 @@ package com.flyfish.framework.config; import com.flyfish.framework.bean.EnumValue; import com.flyfish.framework.enums.NamedEnum; +import com.flyfish.framework.utils.ClassPathResourceScanner; import com.flyfish.framework.utils.StringFormats; import org.apache.commons.lang3.ClassUtils; -import org.reflections.Reflections; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; @@ -13,6 +13,7 @@ import java.util.stream.Collectors; /** * 枚举相关,专门处理枚举 + * * @author wangyu */ public class EnumConfig implements InitializingBean, ImportBeanDefinitionRegistrar { @@ -23,14 +24,13 @@ public class EnumConfig implements InitializingBean, ImportBeanDefinitionRegistr private final Map> values = new HashMap<>(); public EnumConfig() { - Reflections reflections = new Reflections("com.flyfish.project"); - // 得到Resource注解的类 - Set> classSet = reflections.getSubTypesOf(NamedEnum.class); + // 得到枚举类 + Set> 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 values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> { - result.add(new EnumValue(((Enum) item).name(), item.getName())); + 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))); diff --git a/flyfish-dict/pom.xml b/flyfish-dict/pom.xml index b4a5947..0b69516 100644 --- a/flyfish-dict/pom.xml +++ b/flyfish-dict/pom.xml @@ -24,5 +24,9 @@ ${project.version} true + + org.reflections + reflections + diff --git a/flyfish-web/src/main/java/com/flyfish/framework/config/RestBeanAutoConfigure.java b/flyfish-web/src/main/java/com/flyfish/framework/config/RestBeanAutoConfigure.java index 89d420d..ac381e4 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/config/RestBeanAutoConfigure.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/config/RestBeanAutoConfigure.java @@ -12,11 +12,11 @@ import com.flyfish.framework.domain.base.Vo; import com.flyfish.framework.repository.DefaultReactiveRepository; import com.flyfish.framework.repository.DefaultRepository; import com.flyfish.framework.utils.Assert; +import com.flyfish.framework.utils.ClassPathResourceScanner; import com.flyfish.framework.utils.StringFormats; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.reflections.Reflections; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -76,17 +76,15 @@ public class RestBeanAutoConfigure implements ImportBeanDefinitionRegistrar, Res @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry, BeanNameGenerator beanNameGenerator) { log.info("开始注册rest bean..."); - // 获取元数据 + // 获取包路径元数据 Set basePackages = getBasePackages(metadata); - // 扫描包路径,检测RestBean注解的bean - Reflections reflections = new Reflections(basePackages); // repo注册器 RepositoryRegistrar repositoryRegistrar = RepositoryRegistrar.newInstance(metadata) .init(metadata, resourceLoader, environment, registry, beanNameGenerator); // 寻找基本包路径 String basePackage = basePackages.stream().findFirst().orElse("com.flyfish.project"); // 获取被注解的类,开始编译 - Set> classes = reflections.getTypesAnnotatedWith(RestBean.class); + Set> classes = ClassPathResourceScanner.forAnnotation(RestBean.class).scan(basePackages); // 并发编译,快速接入,准备注册的repo Map> compiledClasses = compile(basePackage, classes); // 从repo开始,注册bean diff --git a/flyfish-web/src/main/java/com/flyfish/framework/controller/EnumController.java b/flyfish-web/src/main/java/com/flyfish/framework/controller/EnumController.java index ad96c8d..4171f0a 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/controller/EnumController.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/controller/EnumController.java @@ -3,9 +3,9 @@ package com.flyfish.framework.controller; import com.flyfish.framework.bean.EnumValue; import com.flyfish.framework.bean.Result; import com.flyfish.framework.enums.NamedEnum; +import com.flyfish.framework.utils.ClassPathResourceScanner; import com.flyfish.framework.utils.StringFormats; import org.apache.commons.lang3.ClassUtils; -import org.reflections.Reflections; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @@ -30,14 +30,12 @@ public class EnumController { private final Map> values = new HashMap<>(); public EnumController() { - Reflections reflections = new Reflections("com.flyfish.project", "com.flyfish.framework"); - // 得到Resource注解的类 - Set> classSet = reflections.getSubTypesOf(NamedEnum.class); + Set> 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 values = Arrays.stream(clazz.getEnumConstants()).reduce(new ArrayList<>(), (result, item) -> { - result.add(new EnumValue(((Enum) item).name(), item.getName())); + 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)));