
package com.fastrpc.annotation;
import com.fastrpc.extension.Holder;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;
@Slf4j
public class ScannerUtils {
static final Map, Set>> cachedAnnotation=new HashMap<>();
static final Set cachedDirName=new HashSet<>() ;
static final boolean recursive = true;
public static void loadClassOrInterface(Class> annotationClazz,String dir) {
String name=annotationClazz.getSimpleName() + "&" + dir;
if (cachedDirName.contains(name)) return;
cachedDirName.add(name);
String packageDirName = dir.replace('.', '/');
Enumeration dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
while (dirs.hasMoreElements()) {
URL url = dirs.nextElement();
String protocol = url.getProtocol();
if ("file".equals(protocol)) {
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
findAndAddClassesInPackageByFile(annotationClazz,dir, filePath);
}
}
} catch (IOException e) {
log.error("load annotation fail :" +e);
cachedDirName.remove(name);
throw new IllegalStateException(e);
}
}
public static void findAndAddClassesInPackageByFile(Class> annotationClazz,String packageName,String packagePath)
{
File dir=new File(packagePath);
if (!dir.exists()||!dir.isDirectory())
{
log.error("path does not exist :"+packagePath);
throw new IllegalArgumentException("path does not exist :"+packagePath);
}
File[] dirFiles=dir.listFiles( file-> (recursive&&file.isDirectory())|| (file.getName().endsWith(".class")));
try {
Set> cachedSet=new HashSet<>();
for (File file:dirFiles)
{
if (file.isDirectory())
{
findAndAddClassesInPackageByFile(annotationClazz,packageName+"."+file.getName(),file.getAbsolutePath());
}else{
// 若为.class文件
String className=file.getName().substring(0,file.getName().length()-6);
Class> clazz=Thread.currentThread().getContextClassLoader().loadClass(packageName+"."+className);
if (clazz.isAnnotationPresent((Class extends Annotation>) annotationClazz))
{
cachedSet.add(clazz);
}
}
}
Set> classes = cachedAnnotation.computeIfAbsent(annotationClazz, aClass -> new HashSet>());
classes.addAll(cachedSet);
cachedAnnotation.put(annotationClazz,classes);
} catch (ClassNotFoundException e) {
log.error(e.getMessage());
throw new IllegalArgumentException("The Class file could not be found ",e);
}
}
public static Set> getClass(Class> annotationClazz,String packageName)
{
if (!cachedDirName.contains(annotationClazz.getName()+"&"+packageName))
loadClassOrInterface(annotationClazz,packageName);
return cachedAnnotation.get(annotationClazz);
}
public static Set> getClass(Class> annotationClazz)
{
return cachedAnnotation.get(annotationClazz);
}
public static void main(String[] args) {
Set> aClass = getClass(Controller.class, "com.fastrpc.service");
if (aClass!=null)
for (Class> cl:aClass) {
System.out.println(cl.getName());
}
}
}
改写自:
Java中利用反射查找使用指定注解的类---找到指定包下的指定注解类_逝者如风-CSDN博客