zoukankan      html  css  js  c++  java
  • 手写web框架之开发一个类加载器

      1 ackage io.renren.common;
      2 
      3 import lombok.extern.slf4j.Slf4j;
      4 import org.apache.commons.lang3.StringUtils;
      5 
      6 import java.io.File;
      7 import java.io.FileFilter;
      8 import java.io.IOException;
      9 import java.net.JarURLConnection;
     10 import java.net.URL;
     11 import java.util.Enumeration;
     12 import java.util.HashSet;
     13 import java.util.Set;
     14 import java.util.jar.JarEntry;
     15 import java.util.jar.JarFile;
     16 
     17 @Slf4j
     18 public class ClassUtil {
     19 
     20     /**
     21      * 获取类加载器
     22      * 获取加载器类的实现比较简单,只需获取当前线程的ClassLoader
     23      */
     24     public static ClassLoader getClassLoader() {
     25         return Thread.currentThread().getContextClassLoader();
     26     }
     27 
     28     /**
     29      * **
     30      * 加载类
     31      * 加载类需要提供类名与是否初始化的标志,这里提到的初始化指是否执行类的静态代码块;
     32      * 为了提高加载类的性能,可以将loadClass方法的isInitialized参数设置false
     33      */
     34     public static Class<?> loadClass(String className, boolean isInitialized) {
     35         Class<?> cls = null;
     36         try {
     37            cls= Class.forName(className, isInitialized, getClassLoader());
     38         } catch (ClassNotFoundException e) {
     39             log.error("load class failure.", e);
     40             throw new RuntimeException(e);
     41         }
     42         return cls;
     43     }
     44 
     45     /**
     46      * 获取指定包名下的所有类
     47      */
     48     public static Set<Class<?>> getClassSet(String packageName) {
     49         Set<Class<?>> classSet = new HashSet<Class<?>>();
     50         try {
     51             Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/"));
     52             while (urls.hasMoreElements()) {
     53                 URL url = urls.nextElement();
     54                 if (url != null) {
     55                     String protocol = url.getProtocol();
     56                     if ("file".equals(protocol)) {
     57                         String packagePath = url.getPath().replace("%20", "");
     58                         addClass(classSet, packagePath, packageName);
     59                     } else if ("jar".equals(protocol)) {
     60                         JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
     61                         if (jarURLConnection != null) {
     62                             JarFile jarFile = jarURLConnection.getJarFile();
     63                             if (jarFile != null) {
     64                                 Enumeration<JarEntry> jarEntries = jarFile.entries();
     65                                 while (jarEntries.hasMoreElements()) {
     66                                     JarEntry jarEntry = jarEntries.nextElement();
     67                                     String jarEntryName = jarEntry.getName();
     68                                     if (jarEntryName.endsWith(".class")) {
     69                                         String className = jarEntryName.substring(0, jarEntryName.lastIndexOf("."))
     70                                                 .replaceAll("/", ".");
     71                                         doAddClass(classSet, className);
     72                                     }
     73                                 }
     74                             }
     75                         }
     76                     }
     77                 }
     78             }
     79         } catch (IOException e) {
     80             log.error("get class set failure.", e);
     81             throw new RuntimeException(e);
     82         }
     83         return classSet;
     84     }
     85 
     86     private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) {
     87         File[] files = new File(packagePath).listFiles(new FileFilter() {
     88             public boolean accept(File file) {
     89                 return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
     90             }
     91         });
     92         for (File file : files) {
     93             String fileName = file.getName();
     94             if (file.isFile()) {
     95                 String className = fileName.substring(0, fileName.lastIndexOf("."));
     96                 if (StringUtils.isNotEmpty(packageName)) {
     97                     className = packageName + "." + className;
     98                 }
     99                 doAddClass(classSet, className);
    100             } else {
    101                 String subPackagePath = fileName;
    102                 if (StringUtils.isNotEmpty(packageName)) {
    103                     subPackagePath = packagePath + "/" + subPackagePath;
    104                 }
    105                 String subPackageName = fileName;
    106                 if (StringUtils.isNotEmpty(packageName)) {
    107                     subPackageName = packageName + "." + subPackageName;
    108                 }
    109                 addClass(classSet, subPackagePath, subPackageName);
    110             }
    111         }
    112     }
    113 
    114     private static void doAddClass(Set<Class<?>> classSet, String className) {
    115         Class<?> cls = loadClass(className, true);
    116         classSet.add(cls);
    117     }

    实现扫描包路径下类的功能

  • 相关阅读:
    11.13 同步异步协程
    GIL及进程池
    线程
    守护进程-互斥锁-IPC
    进程
    网络编程
    异常的处理
    面向对象编程2
    第一章 python学习,个人对计算机硬件的一些理解
    ActiveReports之直接打印报表
  • 原文地址:https://www.cnblogs.com/duan2/p/11748058.html
Copyright © 2011-2022 走看看