ByteBuddy AgentBuilder动态添加的构造方法子类Transformer无法引用问题
问题原因&解决方案
你的配置存在3个核心问题,逐一修正即可解决:
1. 构造方法匹配范围错误
你当前给子类写的Transformer里,构造方法匹配器没有指定所属类,Byte Buddy默认只会在**当前待增强的子类(即B)**中搜索符合条件的构造,自然找不到父类A中新增的构造。你需要在匹配器中加declaredBy(A.class)指定搜索父类的构造。
2. Java语法逻辑错误
super("str", 0)这种父类构造调用,只能在子类构造方法的第一行使用,不允许在普通成员方法中调用。你如果要实现对应逻辑,应该给子类新增构造方法,而非普通的newMethod。
3. 类加载顺序风险
如果子类B比父类A先被类加载器加载,处理B的Transformer运行时,A还没被增强,也会找不到新增的构造。需要保证父类A优先被处理。
修正后的代码示例
合并两个Transformer到同一个AgentBuilder(保证执行顺序)
new AgentBuilder.Default() // 先处理父类A的增强 .type(named("A")) .transform((builder, typeDescription, classLoader, module) -> builder.defineConstructor(Visibility.PROTECTED) .withParameter(String.class) .withParameter(Integer.class) .intercept( // 这里指定调用Base类的双参构造,避免匹配歧义 MethodCall.invoke(isConstructor() .and(declaredBy(Base.class)) .and(takesArguments(String.class, Object.class))) .withArgument(0, 1))) // 再处理A的子类增强 .and() .type(isSubTypeOf(A.class).and(not(named("A")))) .transform((builder, typeDescription, classLoader, module) -> // 给子类新增构造方法,而非普通成员方法 builder.defineConstructor(Visibility.PUBLIC) .intercept( // 指定搜索父类A的双参构造 MethodCall.invoke(isConstructor() .and(declaredBy(A.class)) .and(takesArguments(String.class, Integer.class))) .with("str", 0))) .installOn(instrumentation);
额外说明
如果你确实需要在普通方法中触发父类构造的逻辑,只能通过反射调用A.class.getDeclaredConstructor(String.class, Integer.class).newInstance(...)实现,无法直接用super()语法。
内容的提问来源于stack exchange,提问作者shardul94
相关产品推荐
相关产品推荐

