《Java知識應用》Jar包解析

前言

工作上遇到需要解析Jar包的情況,需要將Jar包裏面的類文件獲取出來,然後動態調用。

案例

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ConfigureJar {

    public static void main(String[] args) throws Exception {
        String path = "E:\\GitHub\\study\\MyProcedure\\lib\\compiler-1.0.jar";//外部jar包的路徑
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();//所有的Class對象
        Map<Class<?>, Annotation[]> classAnnotationMap = new HashMap<Class<?>, Annotation[]>();//每個Class對象上的註釋對象
        Map<Class<?>, Map<Method, Annotation[]>> classMethodAnnoMap = new HashMap<Class<?>, Map<Method,Annotation[]>>();//每個Class對象中每個方法上的註釋對象

        JarFile jarFile = new JarFile(new File(path));
        URL url = new URL("file:" + path);
        ClassLoader loader = new URLClassLoader(new URL[]{url});//自己定義的classLoader類,把外部路徑也加到load路徑裏,使系統去該路經load對象
        Enumeration<JarEntry> es = jarFile.entries();
        while (es.hasMoreElements()) {
            JarEntry jarEntry = (JarEntry) es.nextElement();
            String name = jarEntry.getName();
            if(name != null && name.endsWith(".class")){//只解析了.class文件,沒有解析裏面的jar包
                //默認去系統已經定義的路徑查找對象,針對外部jar包不能用
                Class<?> c = loader.loadClass(name.replace("/", ".").substring(0,name.length() - 6));//自己定義的loader路徑可以找到
                System.out.println(c);
                classes.add(c);
                Annotation[] classAnnos = c.getDeclaredAnnotations();
                classAnnotationMap.put(c, classAnnos);
                Method[] classMethods = c.getDeclaredMethods();
                Map<Method, Annotation[]> methodAnnoMap = new HashMap<Method, Annotation[]>();
                for(int i = 0;i<classMethods.length;i++){
                    Annotation[] a = classMethods[i].getDeclaredAnnotations();
                    methodAnnoMap.put(classMethods[i], a);
                }
                classMethodAnnoMap.put(c, methodAnnoMap);
            }
        }
        System.out.println(classes.size());
    }
}

運行結果:

總結

記錄一下代碼實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章