当前位置: 首页 > 知识库问答 >
问题:

字节伙伴(字节码操作)拦截器不工作:没有

颜宸
2023-03-14

我必须将注释XmlElementWrapper和XmlElement添加到列表类型的字段,但是这些注释需要名称。我想把属性名设置为字段名。我愿意:

   new ByteBuddy()
                                .redefine(className)
                                .method(ElementMatchers.isGetter().and(ElementMatchers.nameStartsWith("get")))
                                .intercept(MethodDelegation.to(SetterListInterceptor.class))
                                .make();
                       //save in .class file (overwrite)
                        List<String> setFields = SetterListInterceptor.get_fieldsList();
                        for (String field : setFields) {
                            new ByteBuddy(ClassFileVersion.JAVA_V7)
                                    .redefine(className)
                                    .field(ElementMatchers.named(field))
                                    .annotateField(AnnotationDescription.Builder.ofType(XmlElementWrapper.class).define("name", "Wrapper" + field).build(),
                                            AnnotationDescription.Builder.ofType(XmlElement.class).define("name",  "element" + field ).build()
                                ).make()
                                .saveIn(_outputDirectory.getParent().toFile());
                        }

这是我的拦截器:

public class SetterListInterceptor {

    public static final String GET_SIGNATURE = "get";
    //questa è la lista delle proprietà di tipo java.util.List' trovate nella classe in oggetto (una istanza di questa classe per classe)
    private static List<String> _fieldsList = new LinkedList<>();


    public static void getter(@Origin Method m) {
        String mname = m.getName();
        if (m.getReturnType().getCanonicalName().equals("java.util.List")) {
            String fieldname = mname.substring(mname.indexOf(GET_SIGNATURE) + 3);
            _fieldsList.add(fieldname);
        }
    }


    public static List<String> get_fieldsList() {
        List<String> temp = new LinkedList<>();
        temp.addAll(_fieldsList);
        _fieldsList = new LinkedList<>();
        return temp;
    }
}

这是目标类的一部分:

package drift.drift.thrift.api.sigs534;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.11.0)", date = "2018-06-18")
public class tTOPR implements org.apache.thrift.TBase<tTOPR, tTOPR._Fields>, java.io.Serializable, Cloneable, Comparable<tTOPR> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("tTOPR");

  private static final org.apache.thrift.protocol.TField CDIPAPP_FIELD_DESC = new org.apache.thrift.protocol.TField("CDIPAPP", org.apache.thrift.protocol.TType.I64, (short)1);
  private static final org.apache.thrift.protocol.TField COPR_FIELD_DESC = new org.apache.thrift.protocol.TField("COPR", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField CTERATT_FIELD_DESC = new org.apache.thrift.protocol.TField("CTERATT", org.apache.thrift.protocol.TType.STRING, (short)3);
  private static final org.apache.thrift.protocol.TField CUBS_FIELD_DESC = new org.apache.thrift.protocol.TField("CUBS", org.apache.thrift.protocol.TType.STRING, (short)4);
  private static final org.apache.thrift.protocol.TField DSESATT_FIELD_DESC = new org.apache.thrift.protocol.TField("DSESATT", org.apache.thrift.protocol.TType.STRING, (short)5);
  private static final org.apache.thrift.protocol.TField SAZILST_FIELD_DESC = new org.apache.thrift.protocol.TField("SAZILST", org.apache.thrift.protocol.TType.STRING, (short)6);
  private static final org.apache.thrift.protocol.TField XOPR_FIELD_DESC = new org.apache.thrift.protocol.TField("XOPR", org.apache.thrift.protocol.TType.STRING, (short)7);
  private static final org.apache.thrift.protocol.TField XSTT_FIELD_DESC = new org.apache.thrift.protocol.TField("XSTT", org.apache.thrift.protocol.TType.STRING, (short)8);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new tTOPRStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new tTOPRTupleSchemeFactory();

  public long CDIPAPP; // optional
  public java.lang.String COPR; // optional
  public java.lang.String CTERATT; // optional
  public java.lang.String CUBS; // optional
  public java.lang.String DSESATT; // optional
  public java.lang.String SAZILST; // optional
  public java.lang.String XOPR; // optional
  public java.lang.String XSTT; // optional

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
...
}
....
..
  private static class tTOPRStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    public tTOPRStandardScheme getScheme() {
      return new tTOPRStandardScheme();
    }
  }
..
..
}

但我有一个例外:

[public static void factory.framework.SetterListInterceptor.getter(java.lang.reflect.Method)、public static java.util.List factory.framework.SetterListInterceptor.get_fieldsList()]都不允许从public drift进行委派。漂流节约应用程序编程接口。sigs534。tTOPR$tTOPR标准方案漂移。漂流节约应用程序编程接口。sigs534。tTOPR$tTOPR标准架构工厂。getScheme()-

发生了什么?任何解决方案都值得赞赏。

对不起,错误的类名SetterInterceptor,我必须重命名为GetterInterceptor(不要混淆)非常感谢

罗比

共有1个答案

楚瑞
2023-03-14

getter拦截器返回val,而拦截的方法应该返回一个值。因此,Byte Buddy不映射方法。

 类似资料:
  • 我试图通过java应用程序中的所有外部调用传递监视/跟踪信息。为了使其透明,我尝试使用byte-buddy,但在使其工作时遇到了一些困难。 为了跟踪每个传入的(http)请求,我截获了HttpServlet。service(),从HttpServletRequest中提取令牌头,并将其放在名为TokenHolder的类中的静态ThreadLocal中。 为了跟踪每个传出(超文本传输协议)请求,我拦

  • 我正在尝试用Byte Buddy拦截构造函数调用,这是我的示例代码: 我看到了这个相关的问题,但是,我得到了一个冲突异常(就好像构造函数被定义了两次)。

  • 问题内容: 使用诸如或的库,是否有一种方法可以在设置了类字段的值时将字节码指令添加到类中以执行代码? 例如,假设我有此类: 假设一段代码包含此行: 我希望此指令被拦截,因此将标志设置为。我知道这对于setter方法是可能的-因为可以通过字节码操作来修改类方法,但是我想对 字段 做同样的事情。 这可能吗?如果可以, 怎么 办? 编辑 我想避免修改访问该类的代码部分,我正在寻找一种方法来将拦截代码保留

  • 如何在构造函数拦截器中启动对象字段? 我在Buddy代码中创建了一个字节构造函数。 构造函数首先将参数保存到私有字段。然后它创建集合。然后它调用以下拦截器来填充该集合。 最好在拦截器中实例化variableNamedField字段,因为事实证明,每次创建新的类实例时,variableNamedField字段都是用相同的HashMap对象实例化的。但是,我只能通过@FieldValue注释将现有字段

  • 我想读取一个二进制文件,并对每个字节做一些操作。我想测试我是否正确地操作了字节。我想将一个字节variable1设置为“00000000”,然后将另一个字节variable2设置为“00001111”,或者它们是newvariable=variable1variable2,将newvariable<<4位,然后打印出int值。

  • 京东金融 App介绍 [京东金融](jr.jd.com)京东金融是京东数字科技集团旗下专注于金融科技服务的重要业务板块。 京东金融始终基于强大的数字科技能力,致力于为让消费者享受专业、安全的数字金融服务,旗下包含个人和企业两大服务体系。 在个人金融领域,“京东金融App”作为载体,通过独有的大数据技术及人工智能风控能力,携手400多家银行、120余家保险公司、110余家基金公司,已为过亿的消费者精