Java 在类加载器中加载Spring引导类
我需要阅读一个Spring引导jar并将所有类加载到一个类加载器上 我的问题是,在spring中,引导类位于“/boot-INF/classes”目录,而不是根目录 有人知道如何在类加载器中加载这些类吗 我尝试这样做:Java 在类加载器中加载Spring引导类,java,spring,spring-boot,classloader,Java,Spring,Spring Boot,Classloader,我需要阅读一个Spring引导jar并将所有类加载到一个类加载器上 我的问题是,在spring中,引导类位于“/boot-INF/classes”目录,而不是根目录 有人知道如何在类加载器中加载这些类吗 我尝试这样做: private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException { return URLClassLoader .
private URLClassLoader getURLClassLoaderFromJar(Path jarPath) throws MalformedURLException {
return URLClassLoader
.newInstance(new URL[] { new URL("jar:file:" + jarPath.toAbsolutePath().toString() + "!/") });
}
这会加载jar,但不会加载/BOOT-INF/classes中的类研究一下spring BOOT如何加载第三方(Liquibase)类,我会这样做: 假设您知道要加载的包名
Resource[] scan(ClassLoader loader, String packageName) throws IOException {
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(
loader);
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(packageName) + "/**/*.class";
Resource[] resources = resolver.getResources(pattern);
return resources;
}
void findAllClasses(String packageName, ClassLoader loader) throws ClassNotFoundException {
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(
loader);
try {
Resource[] resources = scan(loader, packageName);
for (Resource resource : resources) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
ClassUtils.forName(reader.getClassMetadata().getClassName(), loader)
}
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
还可以将类加载器与已加载的jar一起使用:
findallclass(“com.package”,getURLClassLoaderFromJar(pathToJar))代码>
此变体可以安全地与Spring Boot一起使用
可执行jar我最终选择在临时目录上解压de jar,并使用以下条目创建URLClassloader:
一个到根目录。
一个到BOOT-INF/classes
BOOT-INT/lib中的每个jar对应一个
Path warDirectory = decompressWar(absolutePathFile);
File rootDir = new File(warDirectory.toAbsolutePath().toString());
File springBootDir = new File(warDirectory.toAbsolutePath().toString() + "/BOOT-INF/classes/");
List<URL> listaURL = new ArrayList<URL>();
listaURL.add(rootDir.toURI().toURL());
listaURL.add(springBootDir.toURI().toURL());
//This scan the BOOT-INF/lib folder and return a List<URL> with all the libraries.
listaURL.addAll(getURLfromSpringBootJar(warDirectory));
URL[] urls = new URL[listaURL.size()];
urls = listaURL.toArray(urls);
cl = new URLClassLoader(urls);
//This explore the JAR and load all the .class fulies to get the className.
resultClassesBean = loadJars(Collections.singletonList(pathJarFile), cl);
if(resultClassesBean != null && resultClassesBean.getListResultClasses() != null && !resultClassesBean.getListResultClasses().isEmpty()) {
for(String clazz : resultClassesBean.getListResultClasses()) {
cl.loadClass(clazz);
}
}
Path-warddirectory=decompressWar(绝对路径文件);
File rootDir=新文件(warddirectory.toabsolutionpath().toString());
File springBootDir=新文件(warddirectory.toabsolutionpath().toString()+“/BOOT-INF/classes/”;
List listaul=new ArrayList();
add(rootDir.toURI().toul());
add(springBootDir.toURI().toul());
//这将扫描BOOT-INF/lib文件夹并返回包含所有库的列表。
addAll(getURLfromSpringBootJar(warddirectory));
URL[]URL=新URL[listaURL.size()];
URL=listaURL.toArray(URL);
cl=新的URLClassLoader(URL);
//这将探索JAR并加载所有.class文件以获得类名。
resultClassBean=loadJars(Collections.singletonList(pathJarFile),cl);
如果(ResultClassBean!=null&&ResultClassBean.getListResultClasses()!=null&&ResultClassBean.getListResultClasses().isEmpty()){
对于(字符串clazz:ResultClassBean.getListResultClasses()){
cl.loadClass(clazz);
}
}
已编辑添加信息。请尝试此功能。谢谢,我正在尝试此功能。仅使用根目录上的类。如果类位于目录中,则抛出ClassNotFoundExceptionTanks,但我不喜欢使用SPRING或第三方依赖项。