mirror of
https://github.com/wxd-gaming/wxdgaming.boot.git
synced 2026-05-07 06:35:49 +08:00
【新增】远程classloader
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package wxdgaming.boot.agent.loader;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.tools.JavaFileObject;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* 远程loader
|
||||
*
|
||||
* @author: Troy.Chen(無心道, 15388152619)
|
||||
* @version: 2024-07-05 14:08
|
||||
**/
|
||||
@Getter
|
||||
public class RemoteClassLoader extends URLClassLoader {
|
||||
|
||||
public static RemoteClassLoader build(ClassLoader parent, String... urls) {
|
||||
try {
|
||||
URL[] _ruls = new URL[urls.length];
|
||||
ArrayList<String> resources = new ArrayList<>();
|
||||
ArrayList<String> classResources = new ArrayList<>();
|
||||
for (int i = 0, urlsLength = urls.length; i < urlsLength; i++) {
|
||||
String url = urls[i];
|
||||
URI uri = URI.create(url);
|
||||
_ruls[i] = uri.toURL();
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(uri.toURL().openStream())) {
|
||||
ZipEntry nextEntry = null;
|
||||
while ((nextEntry = zipInputStream.getNextEntry()) != null) {
|
||||
resources.add(nextEntry.getName());
|
||||
// System.out.println("resource:" + nextEntry.getName());
|
||||
if (!nextEntry.isDirectory() && nextEntry.getName().endsWith(JavaFileObject.Kind.CLASS.extension)) {
|
||||
String replace = nextEntry.getName()
|
||||
.replace("\\", "/")
|
||||
.replace("/", ".");
|
||||
replace = replace.substring(0, replace.length() - JavaFileObject.Kind.CLASS.extension.length());
|
||||
classResources.add(replace);
|
||||
// System.out.println("class:" + replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new RemoteClassLoader(
|
||||
_ruls,
|
||||
parent,
|
||||
Collections.unmodifiableList(resources),
|
||||
Collections.unmodifiableList(classResources)
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private final List<String> classResources;
|
||||
private final List<String> resources;
|
||||
|
||||
public RemoteClassLoader(URL[] urls, ClassLoader parent, List<String> resources, List<String> classResources) {
|
||||
super(urls, parent);
|
||||
this.resources = resources;
|
||||
this.classResources = classResources;
|
||||
}
|
||||
|
||||
public Stream<Class<?>> classStream() {
|
||||
return classStream(null);
|
||||
}
|
||||
|
||||
public Stream<Class<?>> classStream(Predicate<String> test) {
|
||||
Stream<String> stream = classResources.stream();
|
||||
if (test != null) {
|
||||
stream = stream.filter(test);
|
||||
}
|
||||
return stream.map(v -> {
|
||||
try {
|
||||
return this.loadClass(v);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(v, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Class<?>> classes() {
|
||||
return classes(null);
|
||||
}
|
||||
|
||||
public List<Class<?>> classes(Predicate<String> test) {
|
||||
return classStream(test).collect(Collectors.toUnmodifiableList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.experimental.Accessors;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import wxdgaming.boot.agent.exception.Throw;
|
||||
import wxdgaming.boot.agent.loader.ClassDirLoader;
|
||||
import wxdgaming.boot.agent.loader.RemoteClassLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
@@ -254,6 +255,13 @@ public class ReflectContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classLoader instanceof RemoteClassLoader remoteClassLoader) {
|
||||
remoteClassLoader
|
||||
.classStream(v -> v.startsWith(packageName))
|
||||
.forEach(consumer);
|
||||
}
|
||||
|
||||
Enumeration<URL> resources = classLoader.getResources(packagePath);
|
||||
if (resources != null) {
|
||||
URL url = null;
|
||||
@@ -338,7 +346,7 @@ public class ReflectContext {
|
||||
* @param jarPath jar文件路径
|
||||
*/
|
||||
private void findClassByJar(String jarPath, Consumer<Class<?>> consumer) {
|
||||
|
||||
if (jarPath.startsWith("http://") || jarPath.startsWith("https://")) return;
|
||||
String[] jarInfo = jarPath.split("!");
|
||||
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
|
||||
String packagePath = jarInfo[1].substring(1);
|
||||
|
||||
Reference in New Issue
Block a user