按包查找课程
/** * This class is modified from m-m-m reflection util project, whose website is: * http://m-m-m.sourceforge.net/maven/mmm-util/mmm-util-reflect/ * * Copyright (c) The m-m-m Team, Licensed under the Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 */ //package com.nowjava; /** 来 自 时代Java公众号 **/ import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; import java.util.Enumeration; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class Main { public static void findClassesByPackage(String pkgName, boolean includeSubPackages, Set<Class<?>> result)//from NowJava.com throws IOException, ClassNotFoundException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); String path = pkgName.replace('.', '/'); String pathWithPrefix = path + '/'; Enumeration<URL> urls = loader.getResources(path); StringBuilder qualifiedNameBuilder = new StringBuilder(pkgName); qualifiedNameBuilder.append('.'); int qualifiedNamePrefixLength = qualifiedNameBuilder.length(); while (urls.hasMoreElements()) { URL pkgUrl = urls.nextElement(); String urlString = URLDecoder.decode(pkgUrl.getFile(), "UTF-8"); String protocol = pkgUrl.getProtocol().toLowerCase(); if ("file".equals(protocol)) { File pkgDir = new File(urlString); if (pkgDir.isDirectory()) { if (includeSubPackages) { findClassNamesRecursive(pkgDir, result, qualifiedNameBuilder, qualifiedNamePrefixLength); } else { for (String fileName : pkgDir.list()) { String simpleClassName = fixClassName(fileName); if (simpleClassName != null) { qualifiedNameBuilder .setLength(qualifiedNamePrefixLength); qualifiedNameBuilder .append(simpleClassName); Class<?> clazz = Class .forName(qualifiedNameBuilder .toString()); if (!clazz.isInterface() && !clazz.isAnnotation()) { result.add(clazz); } } } } } } else if ("jar".equals(protocol)) { // somehow the connection has no close method and can NOT be disposed JarURLConnection connection = (JarURLConnection) pkgUrl .openConnection(); JarFile jarFile = connection.getJarFile(); Enumeration<JarEntry> jarEntryEnumeration = jarFile .entries(); while (jarEntryEnumeration.hasMoreElements()) { JarEntry jarEntry = jarEntryEnumeration.nextElement(); String absoluteFileName = jarEntry.getName(); if (absoluteFileName.endsWith(".class")) { if (absoluteFileName.startsWith("/")) { absoluteFileName.substring(1); } // special treatment for WAR files... // "WEB-INF/lib/" entries should be opened directly in contained jar if (absoluteFileName.startsWith("WEB-INF/classes/")) { // "WEB-INF/classes/".length() == 16 absoluteFileName = absoluteFileName .substring(16); } boolean accept = true; if (absoluteFileName.startsWith(pathWithPrefix)) { String qualifiedName = absoluteFileName .replace('/', '.'); if (!includeSubPackages) { int index = absoluteFileName.indexOf('/', qualifiedNamePrefixLength + 1); if (index != -1) { accept = false; } } if (accept) { String className = fixClassName(qualifiedName); if (className != null) { Class<?> clazz = Class .forName(className); if (!clazz.isInterface() && !clazz.isAnnotation()) { result.add(clazz); } } } } } } } else { throw new IllegalArgumentException( "Unsupported protocol : " + protocol); } } } private static void findClassNamesRecursive(File pkgDir, Set<Class<?>> result, StringBuilder qualifiedNameBuilder, int qualifiedNamePrefixLength) throws ClassNotFoundException { for (File childFile : pkgDir.listFiles()) { String fileName = childFile.getName(); if (childFile.isDirectory()) { qualifiedNameBuilder.setLength(qualifiedNamePrefixLength); StringBuilder subBuilder = new StringBuilder( qualifiedNameBuilder); subBuilder.append(fileName); subBuilder.append('.'); findClassNamesRecursive(childFile, result, subBuilder, subBuilder.length()); } else { String simpleClassName = fixClassName(fileName); if (simpleClassName != null) { qualifiedNameBuilder .setLength(qualifiedNamePrefixLength); qualifiedNameBuilder.append(simpleClassName); Class&