首页 > 代码库 > [编织消息框架][JAVA核心技术]动态代理应用9-扫描class
[编织消息框架][JAVA核心技术]动态代理应用9-扫描class
之前介绍的annotationProcessor能在编译时生成自定义class,但有个缺点,只能每次添加/删除java文件才会执行,那天换了个人不清楚就坑大了
还记得之前介绍的编译时处理,懒处理,还有个预处理没介绍对吧
预处理:应用程序启动前做的处理,如setup
扫描class处理
1.从ClassLoader 和 System.getProperty("java.class.path") 读取所有classPath
2.解释每个classPath ,用正则匹配jar/class 文件
3.正则提取class文件类名,转换成class给上层处理
1 public class PackageScanner { 2 private static final Logger LOGGER = LoggerFactory.getLogger(PackageScanner.class); 3 4 /** 5 * @param packageNames 6 * 过滤的包名,如果为NULL即扫描所有类 7 */ 8 public static void scan(Consumer<Class<?>> atcion, final String... packageNames) { 9 Set<String> classPath = new HashSet<>();10 Set<String> filterPackage = new HashSet<>();11 if (packageNames == null || packageNames.length == 0) {12 String classpathProp = System.getProperty("java.class.path");13 if (classpathProp != null) {14 String[] classpathEntries = classpathProp.split(File.pathSeparator);15 for (String cpe : classpathEntries) {16 cpe = trimr(cpe, ‘/‘);17 classPath.add(new File(cpe).getAbsolutePath());18 }19 }20 ClassLoader cl = ClassLoader.getSystemClassLoader();21 URL[] urls = ((URLClassLoader) cl).getURLs();22 for (URL url : urls) {23 String path = trimr(url.getPath(), ‘/‘);24 classPath.add(new File(path).getAbsolutePath());25 }26 } else {27 Collections.addAll(classPath, packageNames);28 Collections.addAll(filterPackage, packageNames);29 }30 31 /***32 * 扫描有三种策略33 * 1.jar文件34 * 2.class文件35 * 3.classPath目录36 * */37 38 for (String path : classPath) {39 try {40 if (path.endsWith(".jar")) {41 parseJar(path, filterPackage, atcion);42 }else if (new File(path).isDirectory()) {43 parseFile(path, null, filterPackage, atcion);44 } else {45 final String packageDirectory = path.replace(‘.‘, ‘/‘);46 final Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageDirectory);47 while (urls.hasMoreElements()) {48 final URL url = urls.nextElement();49 if ("file".equals(url.getProtocol())) {50 parseFile(url.getPath(), url.getPath().replace(packageDirectory, ""), filterPackage,atcion);51 } else if ("jar".equals(url.getProtocol())) {52 parseJar(url.getPath(),filterPackage, atcion);53 }54 }55 }56 } catch (Exception exception) {57 throw new RuntimeException(exception);58 }59 }60 }61 }
parseJar,parseFile 比较长,感兴趣读者可查源码分析
有的JAR里的类读会出错,原因是没有依赖完整的包
测试:
1 public class TestScanClass { 2 3 @Test 4 public void testAll() { 5 PackageScanner.scan((clz) -> { 6 // System.out.println(clz); 7 }); 8 } 9 10 @Test11 public void testFilter1() {12 PackageScanner.scan((clz) -> {13 System.out.println(clz);14 } , "com.eyu.onequeue");15 }16 17 @Test18 public void testFilter() {19 Set<Class<?>> values = new HashSet<>();20 PackageScanner.scan((clz) -> {21 QModel modelAnno = ReflectUtil.getAnno(clz, QModel.class);22 if (modelAnno == null) {23 return;24 }25 values.add(clz);26 } , "com.eyu.onequeue");27 for (Class<?> clz : values) {28 if (clz.isInterface()) {29 QRpcFactory.registerSendProxy(clz);30 System.out.println("registerSendProxy : " + clz);31 } else {32 try {33 QRpcFactory.registerReceiveProxy(clz.newInstance());34 System.out.println("registerReceiveProxy : " + clz);35 } catch (Exception e) {36 e.printStackTrace();37 }38 }39 }40 }41 }
[编织消息框架][JAVA核心技术]动态代理应用9-扫描class
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。