我是靠谱客的博主 合适猫咪,这篇文章主要介绍【Java】包扫描与Jar包扫描工具,现在分享给大家,希望可以做个参考。

为什么要用到包扫描? 

         包扫描一般用作于扫描出该包内所有带有某注解的类,并对之进行处理

         包扫描可分为普通包扫描和Jar包扫描


包扫描工具代码:

1.普通包扫描

复制代码
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
// 给定包名及当前文件currentfile private void scanPackage(String packageName, File currentfile) { // 获得currentfile内的所有文件 File[] files = currentfile.listFiles(new FileFilter() { // 内部类方法:根据路径名判断当前是否是文件夹 // 是则返回true // 否则要判断该文件是否是class类型文件,并返回结果 @Override public boolean accept(File pathname) { if (currentfile.isDirectory()) { return true; } return pathname.getName().endsWith(".class"); } }); // 遍历所有的file // 若file是文件夹,则更新路径,递归扫描 for (File file : files) { if (file.isDirectory()) { scanPackage(packageName + "." + file.getName(), file); } else { // 若file非文件夹 // 则要根据目前包路径和file名得到类名 // 我们的包扫描是处理类的: // 所以我不希望他是八大基本类型,注解,接口,及,枚举 String fileName = file.getName().replace(".class", ""); String className = packageName + "." + fileName; try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() ||klass.isInterface() ||klass.isEnum() ||klass.isPrimitive()) { continue; } // 无论普通包扫描和Jar包扫描 // 我们都需要对扫描到的类进行处理 // 如何处理并不由我们扫描的工具决定 // 是由工具使用者决定的 // 所以下面的dealClass必然是抽象方法! dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } }

 2.Jar包扫描

Jar包扫描的思路同普通包扫描

根据Jar包文件找出所有的类,当然要排除八大基本类型,接口,枚举和注解。

然后在通过用户完成对扫描出的class操作

复制代码
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
private void scanPackage(URL url) throws IOException { JarURLConnection jarUrlConnection = (JarURLConnection) url.openConnection(); JarFile jarFile = jarUrlConnection.getJarFile(); Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarName = jarEntry.getName(); if (jarEntry.isDirectory() || !jarName.endsWith(".class")) { continue; } String className = jarName.replace(".class", "").replaceAll("/", "."); try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() ||klass.isInterface() ||klass.isEnum() ||klass.isPrimitive()) { continue; } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }

3.当然,这样还不够“智能”。我能不能根据使用者给我的路径,“智能”判断其在扫描包还是Jar包,答案是肯定的。毕竟上面的都是private

复制代码
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
// 重载:根据类进行类所在包的包扫描 public void packageScanner(Class<?> klass) { packageScanner(klass.getPackage().getName()); } // 根据包名进行包扫描 public void packageScanner(String packageName) { // 将包名转换为路径 String packagePath = packageName.replace(".", "/"); // 得到当前类加载器 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { // 遍历路径下的所有,得到URL,根据URL判断其属性是否Jar // 达到不同处理的目的 Enumeration<URL> resources = classLoader.getResources(packagePath); while (resources.hasMoreElements()) { URL url = resources.nextElement(); if (url.getProtocol().equals("jar")) { scanPackage(url); } else { File file = new File(url.toURI()); if (!file.exists()) { continue; } scanPackage(packageName, file); } } } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } }

整体代码 

复制代码
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
import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URISyntaxException; import java.net.URL; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public abstract class PackageScanner { public PackageScanner() { } public abstract void dealClass(Class<?> klass); public void packageScanner(Class<?> klass) { packageScanner(klass.getPackage().getName()); } public void packageScanner(String packageName) { String packagePath = packageName.replace(".", "/"); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Enumeration<URL> resources = classLoader.getResources(packagePath); while (resources.hasMoreElements()) { URL url = resources.nextElement(); if (url.getProtocol().equals("jar")) { scanPackage(url); } else { File file = new File(url.toURI()); if (!file.exists()) { continue; } scanPackage(packageName, file); } } } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } private void scanPackage(URL url) throws IOException { JarURLConnection jarUrlConnection = (JarURLConnection) url.openConnection(); JarFile jarFile = jarUrlConnection.getJarFile(); Enumeration<JarEntry> jarEntries = jarFile.entries(); while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarName = jarEntry.getName(); if (jarEntry.isDirectory() || !jarName.endsWith(".class")) { continue; } String className = jarName.replace(".class", "").replaceAll("/", "."); try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() ||klass.isInterface() ||klass.isEnum() ||klass.isPrimitive()) { continue; } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void scanPackage(String packageName, File currentfile) { File[] files = currentfile.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (currentfile.isDirectory()) { return true; } return pathname.getName().endsWith(".class"); } }); for (File file : files) { if (file.isDirectory()) { scanPackage(packageName + "." + file.getName(), file); } else { String fileName = file.getName().replace(".class", ""); String className = packageName + "." + fileName; try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() ||klass.isInterface() ||klass.isEnum() ||klass.isPrimitive()) { continue; } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } }

 

 

 除构造方法外,提供两个public方法 void packageScanner(Class<?> klass) 

                                                       void packageScanner(String packageName)

扫描出  给定类所在包  或  给定包路径  下的所有的类 (用到递归)

用抽象方法提供给工具使用者去决定 如何处理扫描出的类

 

使用方法:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) { new PackageScanner() { @Override public void dealClass(Class<?> klass) { System.out.println(klass.getName()); } }.packageScanner("util.core"); } 或 public static void main(String[] args) { new PackageScanner() { @Override public void dealClass(Class<?> klass) { System.out.println(klass.getName()); } }.packageScanner(XXX.class); }

 

最后

以上就是合适猫咪最近收集整理的关于【Java】包扫描与Jar包扫描工具的全部内容,更多相关【Java】包扫描与Jar包扫描工具内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部