1. 简介

本项目是一个jar包扫描工具,可以支持插件化订制不同的扫描逻辑

支持以下功能:

  • 插件化订制扫描逻辑,让扩展更加容易
  • 将扫描到的文件加载到jvm中以class的形式返回给处理插件,让扫描逻辑写起来更加的容易
  • 支持springBoot jar 的扫描

项目地址:

  • gamma扫描引擎

    • github
    • gitee

1.1 用途

设计gamma的初衷是为了能在ci流水线中快速的检查已经打包好的的业务jar,并且能轻易的扩展扫描器的功能,以及和业务解耦

1.2 为什么不去扫描java文件

对于语法检查等checkstyle插件确实直接扫描java文件是更好的选择,但是扫描java文件意味着解析
难度变大,需要去解析对应字符串到底是属于什么包

如:我想去收集某个项目中有多少个方法标记了 springMVC中的注解@RequestMapping, 同时把这个注解中的入参给统计一下

上述需求如果直接去解析java文件就会很麻烦,因为虽然匹配上了字符串@RequestMapping但还需要去判断他的包名是否是属于
spring, 还需要去解析对应注解中的参数,如果注解中使用了常量,还需要解析对应的常量类,然后才能获取真正的值

1.3 为什么不去直接扫描class文件

通过一些字节码工具,如asm可以直接去解析class文件,这样确实可以解决上面提到扫描java文件中常量和类全称的问题,
但是有一定的门槛,需要去学习字节码的相关知识和对应的操作框架

1.4 gamma的优势

gamma出现就是解决上面2个问题

如果我可以把这个jar文件完全给装载进入jvm中,从jvm中获取到我所有想扫描的class对象, 然后通过反射去获取是否存在@RequestMapping注解,不就
能减少很多的工作量。

对应开发插件的人来说,门槛就仅仅只需要会使用反射即可

所以 gamma的优势 如下:

  • 极低的门槛让你自定义扫描逻辑
  • 插件式的方式自定义处理逻辑

1.4 实际案例

  • spring接口扫描器插件

    • 插件csdn博客
    • github
    • gitee

2. 架构设计

上面简介中提到过,gamma的工作原理是将会 把要扫描的jar完全加载进入到jvm中,然后处理器将会依次获得对应的class对象
,处理器将可以使用反射的方式去处理获得的class对象(如:使用反射来获取对应/方法上面是否存在@RequestMapping注解)

这里的处理器,也就是需要根据实际业务去编写的gamma插件了。

2.1 类加载器

上面提到过,gamma将会把要扫描的jar完全加载进入jvm中,那么类加载器的设计就需要满足以下几点

  • 每个插件之间类加载器相互隔离
  • 每个插件都能够获取到被加载进jvm扫描Jar中的class对象

2.2 jar包的解析

这里jar包的解析分成2种情况

  1. spring boot 的jar

    • springBoot打出的jar格式和普通的jar又一定的区别,所以需要先去获得spring提供的一个类加载器,然后才能通过这个类加载器去获得对应业务class
  2. 普通的java jar

    • 普通的jar如果引入了其他第三方依赖,那么打出来的jar中将会依赖和业务class都混合在一起,可以使用参数 scan.package来指定你想扫描的class路径,而不需要去扫描框架引入的class
    • 对应springBoot的jar来说,因为特殊的jar结构,扫描的将全部都是业务class

注意:

3.快速使用

在本项目的/dist文件夹中下载作者编译好的文件 gamma-bootstrap.jar, 在gamma-bootstrap.jar文件同级目录创建文件夹plugins
plugins文件夹中创建子目录作为插件的名称, 然后把对应的插件jar放入子目录中即可(插件的编写请看4.1章节)

最简结构 如下图所示:

然后输入命令

  java -jar gamma-bootstrap.jar source=你要扫描的jar路径

当然如果你想修改gamma的源码那么修改完成后在项目根路径执行

mvn clean package

执行结束后也会在/dist目录中生成新的 gamma-bootstrap.jar

4. 插件

gamma仅仅只是一个扫描引擎,当扫描到对应的class要如何处理, 需要编写插件来实现

如:

  • spring接口扫描器插件

    • github
    • gitee
    • csdn

4.1 自定义插件

  • clone本仓库,进入gamma-common目录执行maven命令来安装对应的依赖
mvn clean install
  • 创建一个新的maven项目
  • 在新的插件项目中引入依赖
<dependency><groupId>com.chy</groupId><artifactId>gamma-common</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
  • 创建一个类,实现接口
/*** gamma插件的执行接口* 泛型T 为插件需要的配置文件类,如:本插件在配置文件config.properties 中设置了属性 commitId=1234 、 ref=master* 那么泛型T需要定义 一个实体类来接收这2个属性* 如果没有任何的属性对象,这里泛型可以填入 Void* * * @param <T>*/
public interface Processor<T> {/***  配置对象的接收,gamma将会根据配置文件以及jvm参数来生成对应的配置对象*  如果泛型T 设置是Object那么这里注入的将会是一个HashMap对象* @param t*/void setProperty(T t);/*** 处理的核心接口* gamma每扫描到jar中的一个class都会回调该接口* * @param originClass 被扫描jar中的某一个class*/void processor(Class originClass);/*** 当全部扫描完后回调**/void finishProcessor();}
  • 在插件的META-INF目录(如果没有就在resources目录下先创建META-INF目录)下创建文件gamma.plugin文件,里面写上对应你插件Processor
    接口实现类的全路径
  • 执行命令打包成一个插件
mvn clean package

注意: 打出的插件jar需要把对应的第三方依赖也一起打包进插件jar中,可以使用以下配置来完成对应的操作

添加对应的maven插件

 <plugin><artifactId>maven-assembly-plugin</artifactId><executions><execution><!-- 绑定到package生命周期 --><phase>package</phase><goals><goal>single</goal></goals></execution></executions><configuration><descriptorRefs><!-- 将依赖一起打包到 JAR --><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><appendAssemblyId>false</appendAssemblyId></configuration>
</plugin>

5. 配置

gamma中配置分成2类

  • gamma核心配置

    • 该配置用于控制gamma的行为,有固定的参数
  • 插件配置
    • 由插件开发者自己定义的参数配置,每一个插件都可能不相同

同时不管gamma核心配置还是插件配置都有2种设置方式

  • 通过program arguments方式在gamma启动的时候设置如:
java -jar gamma-bootstrap.jar source=你要扫描的jar路径

这里的 source就是通过program arguments设置进入的参数

如果要设置插件的专属参数, 那么在参数前面需要带上插件的名称如:

java -jar gamma-bootstrap.jar source=你要扫描的jar路径 mypl1:url=123

这里的mypl1:url代表的就是给插件mypl1设置参数url

  • 通过配置文件方式设置

创建文件 config.properties 来设置对应的配置

config.properties文件位置的不同所具有的含义也不同,如下图所示

注意: 通过program arguments设置的参数优先级高于配置文件的方式

5.1 gamma核心配置

  • source: 指定要扫描的jar包的位置
  • scan.package: 指定要扫描的包名前缀,不设置将会扫描所有,多个路径可以用逗号分隔

5.2 插件配置

上面提到了插件如何去设置自己的参数,那么设置了之后,在插件中如何去读到对应的参数嗯?

从上面的Processor<T>接口可以看出,需要填入一个泛型T,这个泛型T就是插件自定义的配置类,
当插件被gamma加载的时候,将会回调对应的实现方法void setProperty(T t)来传递生成的配置对象

当然这个配置对象也是有部分规则的,需要在需要注入的配置字段上面打上注解@com.chy.gamma.common.profile.Param
如:

@Data
public class ApiScanProperty {@Paramprivate String ref;@Paramprivate String commitId;@Param(nullable = true)private String appName;@Param("endpoint.topology.host")private String host;
}

那么对应配置文件中的设置为:

endpoint.topology.host=http://127.0.0.1:3222
ref=master
commitId=23123131
appName=chyapp

或者是:

java -jar gamma-bootstrap.jar source=你要扫描的jar路径 插件名称:ref=master 插件名称:endpoint.topology.host=http://127.0.0.1:3222 插件名称:commitId=23123131 插件名称:appName=chyapp

同时注解@Param还有一个参数nullable来控制是否可以缺省某个值,默认是false,及如果没有传入
对应的值将会抛出异常

6. 日志

gamma使用的日志框架是 log4j2框架,虽然对应插件的类加载器相互独立了,但是双亲委派机制的原因
正常去获取到的logger对象 对于所有插件来说是同一个对象,这样所有的日志将会混杂到一起

为了能做到日志之间的相互隔离 在插件中请使用以下代码来获取logger对象

import com.chy.gamma.common.utils.LogUtils;
public static Logger logger = LogUtils.getLogger("类路径");

同时每个插件都可以配置自己的log4j2文件来自定义输出

7. 嵌入式使用

为了使用更方便,或者再开发插件的时候能够更好的测试,gamma也提供了嵌入式的使用方式

注意:使用嵌入的方式只能执行一个插件

  • 安装gamma-embed模块
    进入本项目的gamma-embed模块下,执行命令
mvn clean install
  • 在代码中写入
public static void main(String[] args) {Map<String, String> config = new HashMap<>();//插件的配置信息config.put("endpoint.topology.host","127.0.0.1:8080");config.put("ref","master");config.put("commitId","1234567");config.put("appName","1234567");config.put("scan.package","com.chy,com.chy2,com.example");//生成GammaContainer容器GammaContainer gammaContainer = new GammaContainer("你要扫描的jar路径", config);//执行插件gammaContainer.start(new 你实现的Procession对象);}

jar包扫描工具: gamma相关推荐

  1. JFinal自动扫描表绑定model(包含jar包扫描)

    为什么80%的码农都做不了架构师?>>>    前段时间 @绝望的八皮 写了个自动探测model注册插件,见:http://my.oschina.net/b1412/blog/677 ...

  2. 基于Spring包扫描工具和MybatisPlus逆向工程组件的数据表自动同步机制

    公司产品产出的项目较多.同步数据库表结构工作很麻烦.一个alter语句要跑到N个客户机上执行脚本.超级费时麻烦.介于此,原有方案是把增量脚本放到一resource包下,项目启动时执行逐行执行一次.但由 ...

  3. jar - 操作jar包的工具

    jar - Manipulates Java Archive (JAR) files. jar命令是一种通用的存档和压缩工具,基于ZIP和ZLIB压缩格式. 常用格式: * 创建jar文件 jar c ...

  4. Maven Helper 安装使用(jar 包管理工具)

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 一般用这款插件来查看maven的依赖树.在不使用此插件的情况下,要想查看maven的依赖树就要使用M ...

  5. java 扫描jar包_java 扫描指定包(包括jar包)

    /*未经本人同意,禁止转载. 做工程时,有时候需要扫描指定包,或者指定jar包,甚至扫描指定包下指定类,本文章详细讲解如何扫描,以及智能扫描,小编讲的很详细了仔细看. 以下讲解, 包扫描和jar包扫描 ...

  6. xjar加密后运行错误_XJar: Spring-Boot JAR 包加/解密工具,避免源码泄露以及反编译。...

    XJar Spring Boot JAR 安全加密运行工具,同时支持的原生JAR. 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动,动态解密运行的方案,避免源码泄露或 ...

  7. spring context 学习总结(注解功能,配置文件,jar包)

    目录 一jar包 1.POM.XML文件 总项目的POM.XML文件 公用工具的模块POM.XML文件 子类模块POM.XML文件 二配置文件 2.web.xml文件 总项目的web.xml文件 工具 ...

  8. jmeter 导入java_8. Jmeter导入jar包

    我们都知道Jmeter是Java编写的,所以有很多时候需要用到Java方面的知识.比如Jmeter前置处理器,就用到了很多Java知识.那么本章我们先介绍如何使用Jmeter导人jar包. 工具准备 ...

  9. 使用maven引入Apache poi jar包

    maven构建的项目-->pom.xml文件 eclipse提供Dependencies直接添加依赖jar包的工具:直接搜索poi以及poi-ooxml即可,maven会自动依赖需要的jar包: ...

最新文章

  1. ubuntu下连接mysql出现Access denied for user ‘rose‘@‘localhost‘ (using password: NO)的解决方法
  2. 为什么都说猫有九条命呢
  3. 对于半结构化数据的讲解,这可能是最通俗易懂的一篇文章了
  4. php excel 垂直居中,完美实现文字图片水平垂直居中
  5. HDU 1012 u Calculate e(简单阶乘计算)
  6. checkbox大小缩放
  7. Android Audio System 架构初探(好文)
  8. 诺基亚n1平板电脑刷机教程_诺基亚n1平板电脑刷机教程_诺基亚N1 完整包线刷升级或救砖教程(不分台版;国行)......
  9. Typora设置图片上传服务
  10. python获取第一个字符_Python:获取列表中第一个字符串的第一个字符?
  11. matlab中得到透明背景图片的方法,如何在Matlab中得到透明背景的图片?
  12. 一键清理系统垃圾文件,让你的电脑运行如飞,隐私也更安全!
  13. TensorFlow Serving架构分析
  14. 单端口和双端口的优势_双端口测量和 S参数 - 灵活应用网络分析仪
  15. 【数据结构】链表相关OJ题 (万字详解)
  16. 一元一个脱单盲盒,“线上月老”是门赚钱的好生意吗?
  17. correl函数相关系数大小意义_correl(correl函数相关系数大小意义)
  18. NVS4200M显卡“超频”
  19. 如何用matlab求函数的最值?
  20. 1.5万倍超高回报率、融合盲盒玩法背后,NFT仍是巨鲸乐园

热门文章

  1. Eclipse读取properties文件中文乱码问题
  2. nginx的工作原理与nginx的配置
  3. 先进制造技术论文_轴承先进锻造工艺及制造技术
  4. safari浏览网页打开速度很慢怎样解决
  5. Tomcat启动成功,但是访问项目时或者是localhost:8080时出现404
  6. 第五十七章 Caché 函数大全 $REPLACE 函数
  7. linux 网络编程相关知识
  8. Zookeeper + Centos7 详细安装教程
  9. 线性模型(Linear Model)
  10. 宋登高 php,HDwiki百科建站讲座第一期