[编织消息框架][JAVA核心技术]动态代理应用9-扫描class
之前介绍的annotationProcessor能在编译时生成自定义class,但有个缺点,只能每次添加/删除java文件才会执行,那天换了个人不清楚就坑大了
还记得之前介绍的编译时处理,懒处理,还有个预处理没介绍对吧
预处理:应用程序启动前做的处理,如setup
扫描class处理
1.从ClassLoader 和 System.getProperty("java.class.path") 读取所有classPath
2.解释每个classPath ,用正则匹配jar/class 文件
3.正则提取class文件类名,转换成class给上层处理
public class PackageScanner {
private static final Logger LOGGER = LoggerFactory.getLogger(PackageScanner.class);
/**
* @param packageNames
* 过滤的包名,如果为NULL即扫描所有类
*/
public static void scan(Consumer<Class<?>> atcion, final String... packageNames) {
Set<String> classPath = new HashSet<>();
Set<String> filterPackage = new HashSet<>();
if (packageNames == null || packageNames.length == 0) {
String classpathProp = System.getProperty("java.class.path");
if (classpathProp != null) {
String[] classpathEntries = classpathProp.split(File.pathSeparator);
for (String cpe : classpathEntries) {
cpe = trimr(cpe, '/');
classPath.add(new File(cpe).getAbsolutePath());
}
}
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
String path = trimr(url.getPath(), '/');
classPath.add(new File(path).getAbsolutePath());
}
} else {
Collections.addAll(classPath, packageNames);
Collections.addAll(filterPackage, packageNames);
}
/***
* 扫描有三种策略
* 1.jar文件
* 2.class文件
* 3.classPath目录
* */
for (String path : classPath) {
try {
if (path.endsWith(".jar")) {
parseJar(path, filterPackage, atcion);
}else if (new File(path).isDirectory()) {
parseFile(path, null, filterPackage, atcion);
} else {
final String packageDirectory = path.replace('.', '/');
final Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageDirectory);
while (urls.hasMoreElements()) {
final URL url = urls.nextElement();
if ("file".equals(url.getProtocol())) {
parseFile(url.getPath(), url.getPath().replace(packageDirectory, ""), filterPackage,atcion);
} else if ("jar".equals(url.getProtocol())) {
parseJar(url.getPath(),filterPackage, atcion);
}
}
}
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
}
parseJar,parseFile 比较长,感兴趣读者可查源码分析
有的JAR里的类读会出错,原因是没有依赖完整的包
测试:
public class TestScanClass {
@Test
public void testAll() {
PackageScanner.scan((clz) -> {
// System.out.println(clz);
});
}
@Test
public void testFilter1() {
PackageScanner.scan((clz) -> {
System.out.println(clz);
} , "com.eyu.onequeue");
}
@Test
public void testFilter() {
Set<Class<?>> values = new HashSet<>();
PackageScanner.scan((clz) -> {
QModel modelAnno = ReflectUtil.getAnno(clz, QModel.class);
if (modelAnno == null) {
return;
}
values.add(clz);
} , "com.eyu.onequeue");
for (Class<?> clz : values) {
if (clz.isInterface()) {
QRpcFactory.registerSendProxy(clz);
System.out.println("registerSendProxy : " + clz);
} else {
try {
QRpcFactory.registerReceiveProxy(clz.newInstance());
System.out.println("registerReceiveProxy : " + clz);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
[编织消息框架][JAVA核心技术]动态代理应用9-扫描class的更多相关文章
- [编织消息框架][JAVA核心技术]动态代理介绍
由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...
- [编织消息框架][JAVA核心技术]动态代理应用12-总结
动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...
- [编织消息框架][JAVA核心技术]动态代理应用4
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现
private static Map<Short, Map<Byte, Method>> RECEIVE_METHOD_INFO = new HashMap<>() ...
- [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现
根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...
- [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor
基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...
- [编织消息框架][JAVA核心技术]动态代理应用2
接下来如何实现 第一步:先把服务类,调用方法转换成数字,方便传输 第二步:提取元信息,提取又有三种方式,三种各有优点,最优方式是第一种 1.编译java时处理 2.程序启动时处理,预处理 3.调用时处 ...
- [编织消息框架][JAVA核心技术]动态代理应用5-javassist
基础部份: 修改class我们用到javassist,在pom.xml添加 <properties> <javassist.version>3.18.2-GA</java ...
- [编织消息框架][JAVA核心技术]动态代理应用10-水平扩展方案
服务分为系统服务同用户服务两种 水平扩展是基于系统服务,而拆分方式又有几种方案,按数据跟业务情况来做决策 1.每个服务独立存储(图1):每个服务只负责一个或多个领域实体存储,A服务不能直接修改B服务的 ...
随机推荐
- Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “看看星空,会觉得自己很渺小,可能我们在宇宙中从来就是一个偶然.所以,无论什么事情,仔细想一 ...
- Sublime Text 3 (Build 3126) 最新注册码
Sublime Text 作为程序员开发神器,听说最新版更新了 并且增加了不少新特性.马上到官网下载了最新版 Sublime Text 3 3126 使用了下,反应速度比以前的确更快了.随手找了几个S ...
- SSIS 数据流的连接和查找转换
在SSIS的数据流组件中,SSIS引擎使用Merge Join组件和 Lookup组件实现TSQL语句中的inner join 和 outer join 功能,Lookup查找组件的功能更类似TSQL ...
- C#一定比C++性能差?当然不!破除迷信,从我做起!
几乎所有的程序员在初学编程之时,都被灌输过"托管语言(Java.C#)性能比非托管语言(C.C++)差好多" 的迷信教条.如果你问他们为什么,他们一定会说:托管语言需要通过虚拟机或 ...
- php实现留言板功能
这个小小的留言板功能适合班级内或者公司内部之间的讨论,对话和留言,非常的方便,更重要的是无需网络,对于公司管理层来说是非常乐于常见的, 下面是这个留言板的写法: 1 首先是登录页面: <form ...
- 搭建ftp服务器实现文件共享
FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务. FTP(File Transfer Protocol ...
- Spring使用注解进行事务的管理
使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间 <beans xmlns="http://www.springframework.org/schema/ ...
- 【CNMP系列】VIM编辑器详解
缘起 大学的时候做过Linux内核驱动程序研发,之前写C语言就是用的Vim编辑器,当年的Vim还不如今天之强大,当时的插件也没有现在这么多,只是觉得这个编辑器能满足我想要的所有,查看Linux内核代码 ...
- 【SF】开源的.NET CORE 基础管理系统系列导航
SF是一套基于ASP.NET Core MVC+EFCore+Bootstrap开发出来的基础管理系统,源代码完全开源,可以帮助你解决C#.NET项目中重复编码的繁琐工作,让开发人员远离加班! SF ...
- Java常量笔记
在添加文件名的同时,文件名和内容可以不相同!! 1·Java 常量 常量就是固定不变的量,一旦被定义,它的值就不能被改变. 例实: 书中的代码不全,在这里不补充一下: 书中的源代码: public c ...