av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

java 如何掃描指定包下類(包括jar中的java類)

瀏覽:66日期:2022-08-14 11:04:04

在很多的實(shí)際場景中,我們需要得到某個包名下面所有的類,

包括我們自己在src里寫的java類和一些第三方提供的jar包里的類,那么怎么來實(shí)現(xiàn)呢?

今天帶大家來完成這件事。

src下面的類如何獲取:

首先,比較簡單的是得到我們自己寫的類,我們先來完成這個,

項目的結(jié)構(gòu)圖如下:

java 如何掃描指定包下類(包括jar中的java類)

我故意創(chuàng)建了這么個比較復(fù)雜的項目結(jié)構(gòu),現(xiàn)在我們就來獲取com.baibin包下所有的類,并且打印他們,代碼如下:

import org.junit.Test;import java.io.File;import java.util.ArrayList;import java.util.List;public class Main { List<String> classPaths = new ArrayList<String>(); @Test public void searchClass() throws ClassNotFoundException {//包名String basePack = 'com.baibin';//先把包名轉(zhuǎn)換為路徑,首先得到項目的classpathString classpath = Main.class.getResource('/').getPath();//然后把我們的包名basPach轉(zhuǎn)換為路徑名basePack = basePack.replace('.', File.separator);//然后把classpath和basePack合并String searchPath = classpath + basePack;doPath(new File(searchPath));//這個時候我們已經(jīng)得到了指定包下所有的類的絕對路徑了。我們現(xiàn)在利用這些絕對路徑和java的反射機(jī)制得到他們的類對象for (String s : classPaths) { //把 D:workcode20170401search-classtargetclassescombaibinsearchaA.class 這樣的絕對路徑轉(zhuǎn)換為全類名com.baibin.search.a.A s = s.replace(classpath.replace('/','').replaceFirst('',''),'').replace('','.').replace('.class',''); Class cls = Class.forName(s); System.out.println(cls);} } /** * 該方法會得到所有的類,將類的絕對路徑寫入到classPaths中 * @param file */ private void doPath(File file) {if (file.isDirectory()) {//文件夾 //文件夾我們就遞歸 File[] files = file.listFiles(); for (File f1 : files) {doPath(f1); }} else {//標(biāo)準(zhǔn)文件 //標(biāo)準(zhǔn)文件我們就判斷是否是class文件 if (file.getName().endsWith('.class')) {//如果是class文件我們就放入我們的集合中。classPaths.add(file.getPath()); }} }}

效果如下:

java 如何掃描指定包下類(包括jar中的java類)

總結(jié):這樣的src下面的都比較容易處理,也很容易想到,但是jar包下面的就沒這么簡單了,

但是還是有辦法的。

jar中的類如何獲取:

jar下的類我們可以通過JarURLConnection類來或者,代碼如下:

import org.junit.Test;import java.io.IOException;import java.net.JarURLConnection;import java.net.URL;import java.util.Enumeration;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class JarMain { @Test public void searchClass() throws IOException, ClassNotFoundException {String basePack = 'org.junit';//通過當(dāng)前線程得到類加載器從而得到URL的枚舉Enumeration<URL> urlEnumeration = Thread.currentThread().getContextClassLoader().getResources(basePack.replace('.', '/'));while (urlEnumeration.hasMoreElements()) { URL url = urlEnumeration.nextElement();//得到的結(jié)果大概是:jar:file:/C:/Users/ibm/.m2/repository/junit/junit/4.12/junit-4.12.jar!/org/junit String protocol = url.getProtocol();//大概是jar if ('jar'.equalsIgnoreCase(protocol)) {//轉(zhuǎn)換為JarURLConnectionJarURLConnection connection = (JarURLConnection) url.openConnection();if (connection != null) { JarFile jarFile = connection.getJarFile(); if (jarFile != null) {//得到該jar文件下面的類實(shí)體Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();while (jarEntryEnumeration.hasMoreElements()) { /*entry的結(jié)果大概是這樣: org/ org/junit/ org/junit/rules/ org/junit/runners/*/ JarEntry entry = jarEntryEnumeration.nextElement(); String jarEntryName = entry.getName(); //這里我們需要過濾不是class文件和不在basePack包名下的類 if (jarEntryName.contains('.class') && jarEntryName.replaceAll('/','.').startsWith(basePack)) {String className = jarEntryName.substring(0, jarEntryName.lastIndexOf('.')).replace('/', '.');Class cls = Class.forName(className);System.out.println(cls); }} }} }} }}

通過這兩種方式我們就可以得到指定包名下面所有的類了,這個還是挺有用的,

比如spring中經(jīng)常用來掃描指定包注解的實(shí)現(xiàn)等。

補(bǔ)充:獲取指定包名下的所有類

寫了一個工具類,用于獲取指定包名下的所有類,支持遞歸遍歷,支持注解過濾,可從 classpath (class 文件與 jar 包)中獲取。

import java.io.File;import java.io.FileFilter;import java.lang.annotation.Annotation;import java.net.JarURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.Enumeration;import java.util.List;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class ClassUtil { // 獲取指定包名下的所有類 public static List<Class<?>> getClassList(String packageName, boolean isRecursive) {List<Class<?>> classList = new ArrayList<Class<?>>();try { Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll('.', '/')); while (urls.hasMoreElements()) {URL url = urls.nextElement();if (url != null) { String protocol = url.getProtocol(); if (protocol.equals('file')) {String packagePath = url.getPath();addClass(classList, packagePath, packageName, isRecursive); } else if (protocol.equals('jar')) {JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();JarFile jarFile = jarURLConnection.getJarFile();Enumeration<JarEntry> jarEntries = jarFile.entries();while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith('.class')) {String className = jarEntryName.substring(0, jarEntryName.lastIndexOf('.')).replaceAll('/', '.');if (isRecursive || className.substring(0, className.lastIndexOf('.')).equals(packageName)) { classList.add(Class.forName(className));} }} }} }} catch (Exception e) { e.printStackTrace();}return classList; } // 獲取指定包名下的所有類(可根據(jù)注解進(jìn)行過濾) public static List<Class<?>> getClassListByAnnotation(String packageName, Class<? extends Annotation> annotationClass) {List<Class<?>> classList = new ArrayList<Class<?>>();try { Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll('.', '/')); while (urls.hasMoreElements()) {URL url = urls.nextElement();if (url != null) { String protocol = url.getProtocol(); if (protocol.equals('file')) {String packagePath = url.getPath();addClassByAnnotation(classList, packagePath, packageName, annotationClass); } else if (protocol.equals('jar')) {JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();JarFile jarFile = jarURLConnection.getJarFile();Enumeration<JarEntry> jarEntries = jarFile.entries();while (jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if (jarEntryName.endsWith('.class')) {String className = jarEntryName.substring(0, jarEntryName.lastIndexOf('.')).replaceAll('/', '.');Class<?> cls = Class.forName(className);if (cls.isAnnotationPresent(annotationClass)) { classList.add(cls);} }} }} }} catch (Exception e) { e.printStackTrace();}return classList; } private static void addClass(List<Class<?>> classList, String packagePath, String packageName, boolean isRecursive) {try { File[] files = getClassFiles(packagePath); if (files != null) {for (File file : files) { String fileName = file.getName(); if (file.isFile()) {String className = getClassName(packageName, fileName);classList.add(Class.forName(className)); } else {if (isRecursive) { String subPackagePath = getSubPackagePath(packagePath, fileName); String subPackageName = getSubPackageName(packageName, fileName); addClass(classList, subPackagePath, subPackageName, isRecursive);} }} }} catch (Exception e) { e.printStackTrace();} } private static File[] getClassFiles(String packagePath) {return new File(packagePath).listFiles(new FileFilter() { @Override public boolean accept(File file) {return (file.isFile() && file.getName().endsWith('.class')) || file.isDirectory(); }}); } private static String getClassName(String packageName, String fileName) {String className = fileName.substring(0, fileName.lastIndexOf('.'));if (StringUtil.isNotEmpty(packageName)) { className = packageName + '.' + className;}return className; } private static String getSubPackagePath(String packagePath, String filePath) {String subPackagePath = filePath;if (StringUtil.isNotEmpty(packagePath)) { subPackagePath = packagePath + '/' + subPackagePath;}return subPackagePath; } private static String getSubPackageName(String packageName, String filePath) {String subPackageName = filePath;if (StringUtil.isNotEmpty(packageName)) { subPackageName = packageName + '.' + subPackageName;}return subPackageName; } private static void addClassByAnnotation(List<Class<?>> classList, String packagePath, String packageName, Class<? extends Annotation> annotationClass) {try { File[] files = getClassFiles(packagePath); if (files != null) {for (File file : files) { String fileName = file.getName(); if (file.isFile()) {String className = getClassName(packageName, fileName);Class<?> cls = Class.forName(className);if (cls.isAnnotationPresent(annotationClass)) { classList.add(cls);} } else {String subPackagePath = getSubPackagePath(packagePath, fileName);String subPackageName = getSubPackageName(packageName, fileName);addClassByAnnotation(classList, subPackagePath, subPackageName, annotationClass); }} }} catch (Exception e) { e.printStackTrace();} }}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。如有錯誤或未考慮完全的地方,望不吝賜教。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 中文字幕一区二区三区乱码图片 | 九九av| 中文在线一区二区 | 综合激情久久 | 亚洲国产成人精品久久久国产成人一区 | 久综合| 成人高清在线 | 精品亚洲二区 | 拍真实国产伦偷精品 | 欧美日批 | 亚洲 欧美 另类 综合 偷拍 | 一区二区免费看 | 成人在线免费观看 | 男女羞羞视频在线免费观看 | 亚洲精品一二区 | 国产视频二区 | 欧美一区二区三区久久精品视 | 国产一级在线观看 | 国产亚洲一区精品 | 国产成人精品综合 | 久久精品视频9 | 综合二区| 日韩中文字幕一区二区 | 美女艹b | 99久久精品国产一区二区三区 | 在线一区| 亚洲视频在线一区 | 欧美色成人 | 91精品国产91久久久久久密臀 | 精品国产91乱码一区二区三区 | 久久国产视频播放 | 亚洲欧美一区二区三区视频 | 亚洲国产精品久久久久 | 91福利网 | 亚洲精品免费在线观看 | 在线一区 | 天天干天天插 | 国产高清在线精品 | 国产午夜精品一区二区三区四区 | 国产一区二区三区免费视频 | av第一页|