【问题标题】:Define a method, call and interceptor and delegate to target with ByteBuddy?使用 ByteBuddy 定义方法、调用和拦截器并委托给目标?
【发布时间】:2020-02-20 22:48:25
【问题描述】:

我有一个对象service,它有几种方法,其中一种方法是foo(arg1, arg2)

想要创建一个新的包装类:

  • 只有一个方法_foo一个额外的参数
  • _foo的执行委托给拦截器,返回被忽略
  • 最后,将调用委托给service 上的目标foo

不知何故,我没有这样做:

final List<Class<?>> parameters =
    Arrays.stream(fooMethod.getParameters())
          .map(Parameter::getType)
          .collect(Collectors.toList());

    parameters.add(AdditionalParameter.class);


final DynamicType.Unloaded unloadedType = new ByteBuddy()
    .subclass(Object.class)
    .implement(interfaceType)
    .name(service.getClass().getSimpleName() + "Dynamic")
    .defineMethod(
        "_" + methodName,
        resolveReturnType(fooMethod),
        Modifier.PUBLIC)
    .withParameters(parameters)
    .intercept(to(fooInterceptor).andThen(
        MethodCall.invoke(fooMethod).on(service)
    ))
    .make();

fooInterceptor 是一个InvocatiomHandler 实例:

public class FooInterceptor implements InvocationHandler {
public Object invoke(
    @This final Object proxy,
    @Origin final Method method.
    @AllArguments final Object[] args) {
    ...
    }
}

异常说我的fooService“不接受 0 个参数”。

我可以从拦截器调用service.foo() - 但不使用反射吗?我不能这样做(但还没有玩过那个部分)。

求助??????

编辑:我无法控制service 中的方法,所以我不能简单地将to(service) 与拦截调用一起使用;可能会出现 ByteBuddy 找不到匹配方法的情况。

EDIT2:如果我可以“告诉”ByteBuddy 要绑定的目标方法的名称,那就太棒了。然后我可以在给定提示的情况下使用to(service)

【问题讨论】:

    标签: java code-generation byte-buddy


    【解决方案1】:

    您可以向MethodDelegation 提供匹配器以缩小要考虑的方法:

    MethodDelegation.withDefaultConfiguration().filter(...).to(...)
    

    至于您的MethodCall,您需要指定要包含哪些参数,foo 需要两个参数。由于您的原始参数似乎是等效的,您可以设置:

    MethodCall.invoke(fooMethod).on(service).withAllArguments();
    

    【讨论】:

    • 过滤器成功了 :) 对于MethodCall,并不是所有的参数:除了最后一个。但同样,过滤器看起来像:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2012-08-18
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多