欢迎访问『www.cnblogs.com/blog-ice』

1.自定义类加载器  ExternalClassLoader

2.创建扫描类 ClassPathScanner

package com.tool.scan;

import java.io.File;
import java.util.List;

public class ScanTest {

    public static void main(String[] args) {
        try {
            // 外部文件夹路径
            File externalDir = new File("D:/tem");

            // 扫描指定包下的类
            ClassPathScanner scanner = new ClassPathScanner(externalDir, "a.b");
            List<Class<?>> classes = scanner.scanClasses();

            // 处理注解
            AnnotationProcessor.processAnnotations(classes, MyAnnotation.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


package com.tool.scan;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class ExternalClassLoader extends URLClassLoader {
    public ExternalClassLoader(File directory) throws MalformedURLException {
        super(new URL[]{directory.toURI().toURL()}, Thread.currentThread().getContextClassLoader());
    }

    public Class<?> loadClass(String className) throws ClassNotFoundException {
        return super.loadClass(className);
    }
}


package com.tool.scan;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ClassPathScanner {
    private final ClassLoader classLoader;
    private final String basePackage;

    public ClassPathScanner(File directory, String basePackage) throws MalformedURLException {
        this.classLoader = new ExternalClassLoader(directory);
        this.basePackage = basePackage;
    }

    public List<Class<?>> scanClasses() throws IOException, ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        String path = basePackage.replace('.', '/');

        // 扫描目录
        Enumeration<URL> resources = classLoader.getResources(path);
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            if (resource.getProtocol().equals("file")) {
                File dir = new File(resource.getFile());
                classes.addAll(findClassesInDirectory(dir, basePackage));
            } else if (resource.getProtocol().equals("jar")) {
                String jarPath = resource.getFile().substring(5, resource.getFile().indexOf("!"));
                classes.addAll(findClassesInJar(new File(jarPath), path));
            }
        }

        return classes;
    }

    private List<Class<?>> findClassesInDirectory(File directory, String packageName) throws ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        if (!directory.exists()) {
            return classes;
        }

        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    classes.addAll(findClassesInDirectory(file, packageName + "." + file.getName()));
                } else if (file.getName().endsWith(".class")) {
                    String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
                    classes.add(classLoader.loadClass(className));
                }
            }
        }

        return classes;
    }

    private List<Class<?>> findClassesInJar(File jarFile, String path) throws IOException, ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        try (JarFile jar = new JarFile(jarFile)) {
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String name = entry.getName();
                if (name.startsWith(path) && name.endsWith(".class")) {
                    String className = name.replace('/', '.').substring(0, name.length() - 6);
                    classes.add(classLoader.loadClass(className));
                }
            }
        }
        return classes;
    }
}


package com.tool.scan;

import java.lang.annotation.Annotation;
import java.util.List;

public class AnnotationProcessor {
    public static <A extends Annotation> void processAnnotations(List<Class<?>> classes, Class<A> annotationClass) {
        for (Class<?> clazz : classes) {
            if (clazz.isAnnotationPresent(annotationClass)) {
                A annotation = clazz.getAnnotation(annotationClass);
                System.out.println("类 " + clazz.getName() + " 标注了 " + annotationClass.getSimpleName() + " 注解");
                // 处理注解属性
                processAnnotationAttributes(annotation);
            }
        }
    }

    private static <A extends Annotation> void processAnnotationAttributes(A annotation) {
        // 这里可以通过反射获取注解的属性值
        java.lang.reflect.Method[] methods = annotation.annotationType().getDeclaredMethods();
        for (java.lang.reflect.Method method : methods) {
            try {
                System.out.println("  属性: " + method.getName() + " = " + method.invoke(annotation));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

posted on 2025-07-09 20:27  仙路尽头谁为峰  阅读(6)  评论(0)    收藏  举报
这里是自由发挥的天堂