SpringBoot自定义maven

网友投稿 208 2022-10-28

SpringBoot自定义maven

目录背景项目配置编译拦截 ASM插桩项目使用

背景

公司开发框架增加了web系统license授权证书校验模块,实行一台机器一个授权证书,初步方案是增加拦截器针对全局请求进行拦截校验,评估后认为校验方式单一,应该增加重要工具类,业务service实现中每个方法的进行校验,因为涉及代码量较大硬编码工作困难,故选择通过自定义maven插件在编译期间进行动态代码插桩操作

项目配置

新建maven项目设置打包方式

maven-plugin

增加依赖项

org.apache.maven

maven-plugin-api

3.5.2

org.apache.maven.plugin-tools

maven-plugin-annotations

3.5.2

provided

org.apache.maven

maven-project

2.2.1

org.ow2.asm

clQtVvasm

9.0

build内容配置

org.apache.maven.plugins

maven-plugin-plugin

3.5

org.apache.maven.plugins

maven-compiler-plugin

3.6.1

1.8

1.8

编译拦截

创建编译操作类FramePlugin,继承AbstractMojo并使用Mojo注解标注,output参数是class文件编译后路径

@Mojo(name = "deepcompile", defaultPhase = LifecyclePhase.COMPILE)

public class FramePlugin extends AbstractMojo {

@Parameter(name = "output", defaultValue = "${project.build.directory}")

private File output;

public void execute() throws MojoExecutionException {

File f = ;

if (!f.exists()) {

clQtVv f.mkdirs();

}

try {

insertPile(f);

} catch (Exception e) {

exceptioncount++;

e.printStackTrace();

}

}

ASM插桩

新建ClassVisitor重写visitMethod方法来过滤访问需要插桩的方法,需要排除自带的init方法

public class MethodCoverageClassVisitor extends ClassVisitor {

public MethodCoverageClassVisitor(ClassVisitor classVisitor) {

super(Opcodes.ASM9, classVisitor);

}

@Override

public MethodVisitor visitMethod(int access, String name, String descriptor, String signature,

String[] exceptions) {

final MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);

if (name.equals("")) {

return methodVisitor;

}

return new MethodCoverageMethodVisitor(Opcodes.ASM9, methodVisitor);

}

}

新建MethodVisitor重写visitCode方法针对方法内部字节码进行自定义操作,这里是使用框架内部封装好的一个静态方法来校验license证书

public class MethodCoverageMethodVisitor extends MethodVisitor {

public MethodCoverageMethodVisitor(int api, MethodVisitor methodVisitor) {

super(api, methodVisitor);

}

@Override

public void visitCode() {

mv.visitFieldInsn(Opcodes.INVOKESTATIC, "com/xxxx/frame/common/utils/ComplieSDK", "checkLicense", "()V");

}

}

最后在execute中进行文件递归查找调用,就是将已经编译的class文件读取/自定义操作后保存

private void insertPile(File root) throws IOException {

if (root.isDirectory()) {

for (File file : root.listFiles()) {

insertPile(file);

}

}

String className = root.getName().replace(".class", "");

if (root.getName().endsWith(".class")) {

//class筛选

boolean flag = false;

//自定义的class文件筛选条件代码

if (flag) {

System.out.println("【insertPile】:" + className);

FileOutputStream fos = null;

try {

final byte[] instrumentBytes = doInsertPile(root);

fos = new FileOutputStream(root);

fos.write(instrumentBytes);

fos.flush();

} catch (MojoExecutionException e) {

System.out.println("【insertPile-exception】:" + className);

e.printStackTrace();

} finally {

if (fos != null) {

fos.close();

}

}

}

}

}

项目使用

maven-plugin项目执行mvn install安装到本地仓库

框架项目配置自定义maven插件进行打包,配置执行的声明周期为complie(编译),这里goal自定义命令名称需要和mojo注解标注类中指定的name名称一致

com.xxxxx

frame-maven-plugin

1.2.5

deepcompile

compile

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:将当前容器保存为本地镜像
下一篇:发票验证(发票验证真假)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~