163 lines
4.7 KiB
Java
163 lines
4.7 KiB
Java
package util;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Modifier;
|
|
import java.net.JarURLConnection;
|
|
import java.net.URI;
|
|
import java.net.URISyntaxException;
|
|
import java.net.URL;
|
|
import java.util.Enumeration;
|
|
import java.util.List;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.jar.JarEntry;
|
|
import java.util.jar.JarFile;
|
|
|
|
/**
|
|
* Description: des
|
|
* Author: zsx
|
|
* CreateDate: 2019/10/8 17:23
|
|
*/
|
|
public class ClassLoaderHelper {
|
|
|
|
final static ConcurrentHashMap<String, Class<?>> CLS_CACHE = new ConcurrentHashMap<>();
|
|
|
|
public static Class<?> forName(String clsname) throws ClassNotFoundException{
|
|
Class<?> cls = CLS_CACHE.get(clsname);
|
|
if(null == cls){
|
|
cls = Class.forName(clsname);
|
|
CLS_CACHE.put(clsname, cls);
|
|
}
|
|
return cls;
|
|
}
|
|
|
|
/**
|
|
* 获取指定接口的某个包下的所有实现类(不包括接口和抽象类)
|
|
*/
|
|
public static void findLocalClass(String packName, Class<?> classinterface, ClassLoader classLoader, List<Class<?>> classes)
|
|
{
|
|
URI url;
|
|
try
|
|
{
|
|
url = classLoader.getResource(packName.replace(".", "/")).toURI();
|
|
}
|
|
catch(URISyntaxException e1)
|
|
{
|
|
return;
|
|
}
|
|
File file = new File(url);
|
|
file.listFiles((subfile) ->
|
|
{
|
|
if(subfile.isDirectory())
|
|
{
|
|
findLocalClass(packName + "." + subfile.getName(), classinterface,classLoader,classes);
|
|
}
|
|
if(subfile.getName().endsWith(".class"))
|
|
{
|
|
Class<?> clazz = null;
|
|
try
|
|
{
|
|
String classname = packName + "." + subfile.getName().replace(".class", "");
|
|
clazz = classLoader.loadClass(classname);
|
|
}
|
|
catch(ClassNotFoundException e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
if(clazz == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(ClassLoaderHelper.filter(clazz, classinterface))
|
|
{
|
|
classes.add(clazz);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 过滤接口和抽象类
|
|
*/
|
|
public static boolean filter(Class<?> clazz, Class<?> filterclass)
|
|
{
|
|
if(clazz.isInterface())
|
|
{
|
|
return false;
|
|
}
|
|
if(Modifier.isAbstract(clazz.getModifiers()))
|
|
{
|
|
return false;
|
|
}
|
|
return filterclass.isAssignableFrom(clazz);
|
|
}
|
|
|
|
|
|
/**
|
|
* jar包查找
|
|
*/
|
|
public static void findClassJar(final String packName, Class<?> classinterface, ClassLoader classLoader, List<Class<?>> classes)
|
|
{
|
|
String pathName = packName.replace(".", "/");
|
|
JarFile jarFile;
|
|
try
|
|
{
|
|
URL url = classLoader.getResource(pathName);
|
|
JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
|
|
jarFile = jarURLConnection.getJarFile();
|
|
}
|
|
catch(IOException |NullPointerException e)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Enumeration<JarEntry> jarEntries = jarFile.entries();
|
|
while(jarEntries.hasMoreElements())
|
|
{
|
|
JarEntry jarEntry = jarEntries.nextElement();
|
|
String jarEntryName = jarEntry.getName();
|
|
if(jarEntryName.contains(pathName) && !jarEntryName.equals(pathName + "/"))
|
|
{
|
|
if(jarEntry.isDirectory())
|
|
{
|
|
String clazzName = jarEntry.getName().replace("/", ".");
|
|
int endIndex = clazzName.lastIndexOf(".");
|
|
String prefix = null;
|
|
if(endIndex > 0)
|
|
{
|
|
prefix = clazzName.substring(0, endIndex);
|
|
}
|
|
findClassJar(prefix, classinterface,classLoader,classes);
|
|
}
|
|
if(jarEntry.getName().endsWith(".class"))
|
|
{
|
|
Class<?> clazz = null;
|
|
try
|
|
{
|
|
clazz = classLoader.loadClass(jarEntry.getName().replace("/", ".").replace(".class", ""));
|
|
}
|
|
catch(ClassNotFoundException e)
|
|
{
|
|
e.printStackTrace();
|
|
}
|
|
if(clazz == null)
|
|
{
|
|
return;
|
|
}
|
|
if(filter(clazz, classinterface))
|
|
{
|
|
classes.add(clazz);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|