集册 Java实例教程 通过类加载器按包查找

通过类加载器按包查找

欢马劈雪     最近更新时间:2020-01-02 10:19:05

484
通过类加载器按包查找


//package com.nowjava;

import java.io.File;
/*from 时 代 J a v a 公 众 号 - nowjava.com*/

import java.net.URL;

import java.util.ArrayList;

import java.util.Enumeration;


import java.util.List;

import java.util.TreeSet;

import java.util.regex.Pattern;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;


public class Main {

    public static void main(String[] argv) throws Exception {

        String packageName = "nowjava.com";

        Class isAssignableFrom = String.class;/*时 代 J a v a 公 众 号 - nowjava.com*/

        System.out.println(java.util.Arrays.toString(findByPackage(

                packageName, isAssignableFrom)));

    }


    public static Class[] findByPackage(String packageName,

            Class isAssignableFrom) {

        Class[] clazzes = getClassesInPackage(packageName, null);


        if (isAssignableFrom == null) {

            return clazzes;

        } else {

            List<Class> filteredList = new ArrayList<Class>();

            for (Class clazz : clazzes) {

                if (isAssignableFrom.isAssignableFrom(clazz))

                    filteredList.add(clazz);

            }


            return filteredList.toArray(new Class[0]);

        }

    }


    /**

     * Scans all classes accessible from the context class loader which belong to the given package and subpackages.

     * Adapted from http://snippets.dzone.com/posts/show/4831 and extended to support use of JAR files

     *

     * @param packageName The base package

     * @param regexFilter an optional class name pattern.

     * @return The classes

     */

    public static Class[] getClassesInPackage(String packageName,

            String regexFilter) {

        Pattern regex = null;

        if (regexFilter != null)

            regex = Pattern.compile(regexFilter);


        try {

            ClassLoader classLoader = Thread.currentThread()

                    .getContextClassLoader();

            assert classLoader != null;

            String path = packageName.replace('.', '/');

            Enumeration<URL> resources = classLoader.getResources(path);

            List<String> dirs = new ArrayList<String>();

            while (resources.hasMoreElements()) {

                URL resource = resources.nextElement();

                dirs.add(resource.getFile());

            }

            TreeSet<String> classes = new TreeSet<String>();

            for (String directory : dirs) {

                classes.addAll(findClasses(directory, packageName, regex));

            }

            ArrayList<Class> classList = new ArrayList<Class>();

            for (String clazz : classes) {

                classList.add(Class.forName(clazz));

            }

            return classList.toArray(new Class[classes.size()]);

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }


    /**

     * Recursive method used to find all classes in a given path (directory or zip file url).  Directories

     * are searched recursively.  (zip files are

     * Adapted from http://snippets.dzone.com/posts/show/4831 and extended to support use of JAR files

     *

     * @param path   The base directory or url from which to search.

     * @param packageName The package name for classes found inside the base directory

     * @param regex       an optional class name pattern.  e.g. .*Test

     * @return The classes

     */

    private static TreeSet<String> findClasses(String path,

            String packageName, Pattern regex) throws Exception {

        TreeSet<String> classes = new TreeSet<String>();

        if (path.startsWith("file:") && path.contains("!")) {

            String[] split = path.split("!");

            URL jar = new URL(split[0]);

            ZipInputStream zip = new ZipInputStream(jar.openStream());

            ZipEntry entry;

            while ((entry = zip.getNextEntry()) != null) {

                if (entry.getName().endsWith(".class")) {

                    String className = entry.getName()

                            .replaceAll("[$].*", "")

                            .replaceAll("[.]class", "").replace('/', '.');

                    if (className.startsWith(packageName)

                            && (regex == null || regex.matcher(className)

                                    .matches()))

                        classes.add(className);

                }

            }

        }

        File dir = 
展开阅读全文