forked from Liubsyy/FindInstancesOfClass
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInstancesOfClass.java
126 lines (105 loc) · 4.05 KB
/
InstancesOfClass.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package com.liubs.findinstances.jvmti;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
/**
* 根据类获取所有实例:基于JVMTI实现
* @author Liubsyy
* @date 2023/10/20 10:08 PM
**/
public class InstancesOfClass {
static {
String nativeLib = null;
String osName = System.getProperty("os.name").toLowerCase();
if(osName.contains("mac")) {
nativeLib = "findins.dylib";
}else if(osName.contains("linux")) {
nativeLib = "findins.so";
}else if(osName.contains("windows")) {
nativeLib = "findins.dll";
}
if(null == nativeLib) {
throw new UnsupportedOperationException("不支持当前操作系统"+osName);
}
URL nativeLibURL = InstancesOfClass.class.getClassLoader().getResource(nativeLib);
if(null == nativeLibURL) {
System.out.println("找不到jar包内的"+nativeLib);
}else if("jar".equals(nativeLibURL.getProtocol())) {
//读取jar包里面的链接库,SpringBoot嵌套jar也支持
loadLibraryFromJar(nativeLibURL,nativeLib);
}else {
System.load(nativeLibURL.getPath());
}
}
private static void loadLibraryFromJar(URL nativeLibURL,String nativeLib) {
String path = nativeLibURL.getPath();
//处理jar包的逻辑
//[jar路径] file:/Users/liubs/.m2/repository/io/github/liubsyy/FindInstancesOfClass/1.0.1/FindInstancesOfClass-1.0.2.jar!/findins.dylib
//[SpringBoot嵌套jar] file:/Users/liubs/IdeaProjects/TestSpring/bin/TestSpring.jar!/BOOT-INF/lib/FindInstancesOfClass-1.0.2.jar!/findins.dylib
String jarPath = path.substring("file:".length(), path.indexOf("jar!")+"jar".length());
//路径包含%20替换成空格
try {
jarPath = URLDecoder.decode(jarPath, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//在jar包的目录下生成so/dylib/dll
File curDir = new File(jarPath);
curDir = curDir.getParentFile();
File nativeLibFile = new File(curDir.getAbsolutePath(),nativeLib);
nativeLibFile.deleteOnExit();
try (InputStream is = nativeLibURL.openStream(); OutputStream os = Files.newOutputStream(nativeLibFile.toPath())) {
byte[] buffer = new byte[1024];
int readBytes;
while ((readBytes = is.read(buffer)) != -1) {
os.write(buffer, 0, readBytes);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.load(nativeLibFile.getAbsolutePath());
}
/**
* native方法 : 返回类的实例对象
* @param targetClass 需要查询实例的Class
* @param limitNum 最多返回实例的数量
* @return
*/
public static native Object[] getInstances(Class<?> targetClass,int limitNum);
/**
* 获取类的所有的实例对象
* @param targetClass 需要查询实例的Class
* @return
*/
public static Object[] getInstances(Class<?> targetClass) {
return getInstances(targetClass,Integer.MAX_VALUE);
}
/**
* 返回类的实例对象List
* @param targetClass 需要查询实例的Class
* @param limitNum 最多返回实例的数量
* @return
* @param <T>
*/
public static <T> List<T> getInstanceList(Class<T> targetClass,int limitNum){
List<T> result = new ArrayList<>();
Object[] instances = getInstances(targetClass,limitNum);
for(Object o : instances) {
result.add((T)o);
}
return result;
}
/**
* 获取类的所有实例对象List
* @param targetClass 需要查询实例的Class
* @return
* @param <T>
*/
public static <T> List<T> getInstanceList(Class<T> targetClass){
return getInstanceList(targetClass,Integer.MAX_VALUE);
}
}