字节码增强——使用javassist生成一个类的复制类并添加字段和注解

一、Javassist简介

  • 是在 Java 中编辑字节码的类库。
  • 它使 Java 程序能够在运行时定义一个新类, 并在 JVM 加载时修改类文件。

二、和反射的区别

  • 反射的定义:是让程序在运行时,能够动态获取或修改对象的所有成员变量,调用对象的所有方法。
    可以看到反射只可以获取和修改成员变量,可以调用方法,但不能修改方法。如果想要修改方法、新增属性就要使用到字节码增强技术,即:Javassist,可以通过修改字节码的方式来实现对类结构的修改。

三、背景介绍

用到这个技术是因为产品提了一个需求,要做一个excel表格导出,把用户基本信息和用户的成绩拼接在一起导出为一个表格。
因此我们利用Javassist技术copy一个新的类,把基本信息和成绩拼在一起,再加上@SheetColumn注解即可。

四、引入pom

<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.26.0-GA</version>
</dependency>

五、newScoreCopyClass方法

这个方法是调用ClassBuilder类的方法。
可以看到先初始化了一个我们自己定义的ScoreClassBulder。resultLists是学生们的答题结果集合,因为我们只需要获取每道题的题目信息,获取第一个list就好,之后遍历把每一道题的名字通过addField方法注入到这个Builder类中,最后调用build方法完成构建。

private Class newScoreCopyClass(List<List<CompResultDto>> resultLists) throws Exception {
    ScoreCopyBuilder subClassBuilder = new ScoreCopyBuilder();
    List<CompResultDto> compResults = resultLists.get(i);
    for (int i = 0; i < compResults.size(); i++) {
        CompResultDto rlt = compResults.get(i);
        String name = "score" + i;
        subClassBuilder.addField(Integer.class, name, rlt.getPracticeName());
    }
    return subClassBuilder.build();
}

六、ScoreCopyBuilder类

这里我们具体来拆解一下ScoreCopyBuilder这个类
根据上面调用方法,核心方法有两个:addField注入属性,build方法完成构建。

6.1 addField方法

首先我们是自己定义了一个FieldWrapper内部类作为实体类,来存储每一个属性的3个信息。
字段类型是Integer,字段名称是之前方法调用时传入的score+i,sheetColumnValue也就是生成excel表格的表头内容。
可以看到这个方法只是把新增字段信息封装存入了list中,真正的构建过程应该是在build的时候发生。

    List<FieldWrapper> fieldWrappers = Lists.newArrayList();
    
    /**
     * 添加一个Field
     *
 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值