/** * specified characters provider */ package org.vic.demo.utils; public class CommonCharacters { public static final String _DOT = "."; public static final String _BLANK = ""; public static final String _SLASH_0 = "/"; public static final String _SLASH_1 = "\\"; }
简单的工具
package org.vic.demo.utils; public class VStringUtils { public static boolean isNotEmpty (String string) { if (string != null && (!CommonCharacters._BLANK.equals(string.trim()))) { return true; } return false; } }
package org.vic.demo.utils; import java.util.Arrays; import java.util.Collection; public class VCollectionUtils { public static boolean isNotEmpty (Collection<?> c) { if (c != null && c.size() > 0) { return true; } return false; } public static<T> boolean isNotEmpty(T[] array) { if (array != null) { return isNotEmpty(Arrays.asList(array)); } else { return false; } } }
mimic scanner
只是一个简单的模拟,只扫描给定包路径下的类,不支持多层扫描。如果需要可以在这个基础上改一下。
可以加一个解析传入package路径的类或者方法,把不同的配置转换成多个单独的package,这样就不用修改 这里的解析代码了。
package org.vic.demo.Annotation.scanner; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import org.vic.demo.utils.CommonCharacters; import org.vic.demo.utils.VCollectionUtils; import org.vic.demo.utils.VStringUtils; public class PackageScanner { private static Map<Class<?>, Set<Annotation>> map = new HashMap<>(); private static final String _PROTOCOL_FILE = "file"; private static final String _CLASS_SYMBO = ".class"; private static String[] package_paths = null; private static class PackageScannerHolder { public static PackageScanner instance = new PackageScanner(package_paths); } public static PackageScanner getInstance (String... packagePaths) { package_paths = packagePaths; return PackageScannerHolder.instance; } private PackageScanner (String... packageNames) { if (VCollectionUtils.isNotEmpty(packageNames)) { try { ClassScanner(packageNames); } catch (ClassNotFoundException | IOException e) { e.printStackTrace(); } } } private void ClassScanner (String... packagePaths) throws IOException, ClassNotFoundException { for (String packagePath : packagePaths) { if (VStringUtils.isNotEmpty(packagePath)) { String path = convertPackagePath2FilePath(packagePath); Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(path); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url.getProtocol().equalsIgnoreCase(_PROTOCOL_FILE)) { String fileAbsolutePath = url.getFile(); processor(fileAbsolutePath, packagePath); } } } } } private void processor (String absolutePath, String currentPackagePath) throws ClassNotFoundException { File dir = new File(absolutePath); File[] files = dir.listFiles(); if (VCollectionUtils.isNotEmpty(files)) { for (File file : files) { if (file.isFile()) { String fileName = file.getName(); String className = currentPackagePath + CommonCharacters._DOT + (fileName.replace(_CLASS_SYMBO, CommonCharacters._BLANK)); Class<?> clazz = Class.forName(className); fix(clazz); } } } } private void fix (Class<?> clazz) { Set<Annotation> existingAnnotations = map.get(clazz); if (VCollectionUtils.isNotEmpty(existingAnnotations)) { return; } Annotation[] annotations = clazz.getAnnotations(); if (VCollectionUtils.isNotEmpty(annotations)) { Set<Annotation> set = new LinkedHashSet<Annotation>(); set.addAll(Arrays.asList(annotations)); System.out.println("put class =======" + clazz.getName() + "======= to map!"); map.put(clazz, set); } } private String convertPackagePath2FilePath (String packagePath) { return packagePath.replace(CommonCharacters._DOT, CommonCharacters._SLASH_0); } }