• Java 扫描工具类(基于接口、注解扫描)


    java通过反射的类扫描工具类,通过遍历类的字节码,找到目标文件,通过反射实例化,目标类,可以通过接口和注解两种方式进行扫描。
    
    package com.csnt.scdp.bizmodules.modules.util;
    
    
    
    import java.io.File;
    
    import java.io.IOException;
    
    import java.net.JarURLConnection;
    
    import java.net.URL;
    
    import java.nio.file.*;
    
    import java.nio.file.attribute.BasicFileAttributes;
    
    import java.util.ArrayList;
    
    import java.util.Enumeration;
    
    import java.util.List;
    
    import java.util.Objects;
    
    import java.util.jar.JarEntry;
    
    import java.util.jar.JarFile;
    
    import java.util.stream.Collectors;
    
    
    
    /**
    
    * @Description: 类加载工具类,用来扫描各种各样你幻想中的。。
    
    *
    
    * @author qcsy
    
    * @Copyright qcsy studio
    
    * @date 2020/07/31.
    
    */
    
    public class ClassUtil {
    
    /**
    
    * 类名后缀
    
    */
    
    private static final String class_suffix=".class";
    
    
    
    /**
    
    * 根据类接口查到所有的class
    
    * @param clazz 接口文件
    
    * @return class
    
    */
    
    public static <T> List<Class<T>> getAllClassByInterface(Class<T> clazz) {
    
    List<Class<T>> list = new ArrayList<>();
    
    try {
    
    List<Class> allClass = getAllClass(clazz.getPackage().getName());
    
    /**
    
    * 循环判断路径下的所有类是否实现了指定的接口 并且排除接口类自己
    
    */
    
    for (int i = 0; i < allClass.size(); i++) {
    
    if (clazz.isAssignableFrom(allClass.get(i))) {
    
    if (!clazz.equals(allClass.get(i))) {
    
    // 自身并不加进去
    
    list.add(allClass.get(i));
    
    }
    
    }
    
    }
    
    } catch (Exception e) {
    
    throw new RuntimeException(e);
    
    }
    
    return list;
    
    }
    
    /**
    
    * 根据类接口查到所有的class
    
    * @param clazz 接口文件
    
    * @return class
    
    */
    
    public static List<Class> getAllClassByAnnotation(Class clazz) {
    
    try {
    
    List<Class> allClass = getAllClass(clazz.getPackage().getName());
    
    return allClass.stream().filter((a)->{return a.isAnnotationPresent(clazz);}).collect(Collectors.toList());
    
    } catch (Exception e) {
    
    throw new RuntimeException(e);
    
    }
    
    }
    
    /**
    
    * 根据类接口查到所有的class(指定包名)
    
    * @param clazz 接口文件
    
    * @return class
    
    */
    
    public static List<Class> getAllClassByAnnotation(Class clazz,String packageName) {
    
    try {
    
    List<Class> allClass = getAllClass(packageName);
    
    return allClass.stream().filter((a)->{return a.isAnnotationPresent(clazz);}).collect(Collectors.toList());
    
    } catch (Exception e) {
    
    throw new RuntimeException(e);
    
    }
    
    }
    
    /**
    
    * 从一个指定路径下查找所有的类
    
    *
    
    * @param packagename
    
    */
    
    private static List<Class> getAllClass(String packagename) {
    
    List<String> classNameList = getClassPathsByPackage(packagename);
    
    List<Class> list=classNameList.stream().map((b)->{
    
    try {
    
    return Class.forName(b);
    
    } catch (Throwable e) {
    
    return null;
    
    }
    
    }).filter(Objects::nonNull).distinct().collect(Collectors.toList());
    
    return list;
    
    }
    
    
    
    /**
    
    * 获取某包下所有类
    
    * @param packageName 包名
    
    * @return 类的完整名称
    
    */
    
    public static List<String> getClassPathsByPackage(String packageName) {
    
    List<String> fileNames = null;
    
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    
    String packagePath = packageName.replace(".", "/");
    
    URL url = loader.getResource(packagePath);
    
    if (url != null) {
    
    String type = url.getProtocol();
    
    if (type.equals("file")) {
    
    String fileSearchPath = url.getPath();
    
    fileSearchPath = fileSearchPath.substring(0,fileSearchPath.indexOf("/classes"));
    
    fileNames = getClassPathsByFile(fileSearchPath);
    
    } else if (type.equals("jar")) {
    
    try{
    
    JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
    
    JarFile jarFile = jarURLConnection.getJarFile();
    
    fileNames = getClassPathsByJar(jarFile);
    
    }catch (IOException e){
    
    throw new RuntimeException("open Package URL failed:"+e.getMessage());
    
    }
    
    }else{
    
    throw new RuntimeException("file system not support! cannot load MsgProcessor!");
    
    }
    
    }
    
    return fileNames;
    
    }
    
    
    
    /**
    
    * 从项目文件获取某包下所有类
    
    * @param filePath 文件路径
    
    * @return 类的完整名称
    
    */
    
    private static List<String> getClassPathsByFile(String filePath) {
    
    List<String> classPaths = new ArrayList<String>();
    
    try {
    
    Files.walkFileTree(Paths.get(new File(filePath).getAbsolutePath()), new SimpleFileVisitor<Path>() {
    
    @Override
    
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
    
    String filePath=file.toFile().getPath();
    
    if (filePath.endsWith(class_suffix)) {
    
    filePath = filePath.substring(filePath.indexOf(File.separator+"classes") + 9, filePath.lastIndexOf("."));
    
    filePath = filePath.replace(File.separator, ".").replace("/",".").replace("\\",".");
    
    classPaths.add(filePath);
    
    }
    
    return super.visitFile(file, attrs);
    
    }
    
    });
    
    } catch (Exception e) {
    
    throw new RuntimeException("walk files error!",e);
    
    }
    
    return classPaths;
    
    }
    
    
    
    /**
    
    * 从jar获取某包下所有类
    
    * @return 类的完整名称
    
    */
    
    private static List<String> getClassPathsByJar(JarFile jarFile) {
    
    List<String> myClassName = new ArrayList<String>();
    
    try {
    
    Enumeration<JarEntry> entrys = jarFile.entries();
    
    while (entrys.hasMoreElements()) {
    
    JarEntry jarEntry = entrys.nextElement();
    
    String entryName = jarEntry.getName();
    
    if (entryName.endsWith(class_suffix)) {
    
    entryName = entryName.replace(File.separator, ".").replace("/",".").replace("\\",".").substring(0, entryName.lastIndexOf("."));
    
    myClassName.add(entryName);
    
    }
    
    }
    
    } catch (Exception e) {
    
    throw new RuntimeException("发生异常:"+e.getMessage());
    
    }
    
    return myClassName;
    
    }
    
    
    
    }
  • 相关阅读:
    spring boot banner设置关闭以及关闭特定的自动配置
    spring boot 初始及快速搭建
    spring scheduling 计划任务
    idea database 导入实体带注解
    idea mapper下的方法找不到 Invalid bound statement (not found)
    spring jwt token 认证
    spring event 事件
    FrontEnd-Basis-6th
    FrontEnd-Basis-5th
    FrontEnd-Basis-4th
  • 原文地址:https://www.cnblogs.com/tiancai/p/16055018.html
Copyright © 2020-2023  润新知