perf[graalvm]: use PathMatchingResourcePatternResolver to scan classes

This commit is contained in:
sun
2023-09-06 15:49:31 +08:00
parent 08e03d6ac9
commit 95dccd879f
5 changed files with 70 additions and 27 deletions
@@ -30,8 +30,10 @@ import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* Register runtime hints for the token library
@@ -77,7 +79,9 @@ public class GraalvmNetHints implements RuntimeHintsRegistrar {
classes.add(TripleLSS.class);
// IPacket
var filterClasses = HintUtils.filterAllClass(clazz -> IPacket.class.isAssignableFrom(clazz));
var filterClasses = HintUtils.filterAllClass(Collections.emptyList(), List.of(IPacket.class));
// filter IAttachment
filterClasses = filterClasses.stream().filter(it -> !it.equals(IAttachment.class)).collect(Collectors.toSet());
classes.addAll(filterClasses);
// protocol.xml
@@ -85,7 +89,7 @@ public class GraalvmNetHints implements RuntimeHintsRegistrar {
var resourcePatternResolver = new PathMatchingResourcePatternResolver();
var protocolResources = new HashSet<Resource>();
protocolResources.addAll(List.of(resourcePatternResolver.getResources("classpath*:/**/*protocol*.xml")));
protocolResources.addAll(List.of(resourcePatternResolver.getResources("classpath*:/*protocol*.xml")));
protocolResources.addAll(List.of(resourcePatternResolver.getResources("classpath*:*protocol*.xml")));
for (var protocolResource : protocolResources) {
try {
var protocolXml = StringUtils.bytesToString(IOUtils.toByteArray(protocolResource.getInputStream()));
@@ -22,6 +22,8 @@ import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Register runtime hints for the token library
@@ -44,7 +46,7 @@ public class GraalvmOrmHints implements RuntimeHintsRegistrar {
classes.add(ClassUtils.forName("com.github.benmanes.caffeine.cache.SSLMSA"));
classes.add(ClassUtils.forName("com.github.benmanes.caffeine.cache.PSAMS"));
var filterClasses = HintUtils.filterAllClass(clazz -> clazz.isAnnotationPresent(GraalvmNativeEntityCache.class));
var filterClasses = HintUtils.filterAllClass(List.of(GraalvmNativeEntityCache.class), Collections.emptyList());
classes.addAll(filterClasses);
for (var clazz : classes) {
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -46,7 +47,7 @@ public class GraalvmProtocolHints implements RuntimeHintsRegistrar {
classes.add(XmlModuleDefinition.class);
classes.add(XmlProtocolDefinition.class);
var filterClasses = HintUtils.filterAllClass(clazz -> clazz.isAnnotationPresent(Protocol.class));
var filterClasses = HintUtils.filterAllClass(List.of(Protocol.class), Collections.emptyList());
classes.addAll(filterClasses);
HintUtils.registerRelevantClasses(hints, classes);
@@ -22,7 +22,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/**
* Register runtime hints for the token library
@@ -41,7 +43,7 @@ public class GraalvmStorageHints implements RuntimeHintsRegistrar {
classes.add(StorageData.class);
classes.add(StorageConfig.class);
var filterClasses = HintUtils.filterAllClass(clazz -> clazz.isAnnotationPresent(GraalvmNativeStorage.class));
var filterClasses = HintUtils.filterAllClass(List.of(GraalvmNativeStorage.class), Collections.emptyList());
classes.addAll(filterClasses);
HintUtils.registerRelevantClasses(hints, classes);
@@ -12,10 +12,15 @@
package com.zfoo.boot.graalvm;
import com.zfoo.protocol.collection.ArrayUtils;
import com.zfoo.protocol.collection.CollectionUtils;
import com.zfoo.protocol.util.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import java.io.IOException;
import java.util.HashSet;
@@ -32,32 +37,61 @@ public abstract class HintUtils {
private static final Logger logger = LoggerFactory.getLogger(HintUtils.class);
/**
* 与set有关的所有内部类包括泛型
*/
public static Set<Class<?>> filterAllClass(Predicate<Class<?>> predicate) {
public static Set<Class<?>> filterAllClass(List<Class<?>> annotations, List<Class<?>> interfaces) {
var classes = new HashSet<Class<?>>();
var annotationNames = annotations.stream().map(it -> it.getName()).toList();
var interfaceNames = interfaces.stream().map(it -> it.getName()).toList();
var resourcePatternResolver = new PathMatchingResourcePatternResolver();
var metadataReaderFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
var resources = new HashSet<Resource>();
try {
var classes = new HashSet<Class<?>>();
for (var className : ClassUtils.getAllClasses("")) {
Class<?> clazz = null;
try {
clazz = Class.forName(className);
} catch (Throwable t) {
// do nothing
}
if (clazz == null) {
continue;
}
if (predicate.test(clazz)) {
classes.add(clazz);
}
}
return classes;
resources.addAll(List.of(resourcePatternResolver.getResources("classpath*:/**/*.class")));
resources.addAll(List.of(resourcePatternResolver.getResources("classpath*:*.class")));
} catch (IOException e) {
throw new RuntimeException(e);
}
for (var resource : resources) {
if (!resource.isReadable()) {
continue;
}
Class<?> clazz = null;
try {
var metadataReader = metadataReaderFactory.getMetadataReader(resource);
var clazzMeta = metadataReader.getClassMetadata();
// check annotation
var annoMeta = metadataReader.getAnnotationMetadata();
if (annotationNames.stream().anyMatch(it -> annoMeta.hasAnnotation(it))) {
clazz = ClassUtils.forName(clazzMeta.getClassName());
classes.add(clazz);
continue;
}
// check interface
if (CollectionUtils.isEmpty(interfaces)) {
continue;
}
var metaInterfaces = metadataReader.getClassMetadata().getInterfaceNames();
if (ArrayUtils.isEmpty(metaInterfaces)) {
continue;
}
for(var metaInterface : metaInterfaces) {
if (interfaceNames.stream().anyMatch(it -> it.equals(metaInterface))) {
clazz = ClassUtils.forName(clazzMeta.getClassName());
classes.add(clazz);
break;
}
}
} catch (Throwable t) {
// do nothing
}
}
return classes;
}
public static void registerRelevantClasses(RuntimeHints hints, Set<Class<?>> classes) {