通过Function / Supplier访问lambda参数

时间:2016-06-28 19:03:59

标签: java java-8

我想编写一个实用程序,对一组调用进行(相对)非侵入式的请求和响应记录,我希望使用java-8 lambda / functional接口来完成它。

假设示例客户端调用代码是:

SomeReturn retVal = someObject.doSomething(arg1, arg2);

我希望编写一个可以调用的Recorder实用程序:

SomeReturn retVal = Recorder.withRecording(() -> someObject.doSomething(arg1, arg2))

记录器看起来像:

public static <R> R withRecording(Supplier<R> call) {
    R response = call.get();
    // Record the response
    return response;
}

但是,我无法确定从Supplier捕获请求参数(和请求对象)的方法(正确如此 - Supplier并不关心它)。我认为即使java.util.function.Function也不会帮助我们,因为他们不会自己处理国家。

不诉诸

之类的事情
Object withRecording(Object target, Method method, Object[] arguments)

我们还有其他选择吗?我知道我们可以使用AOP作为解决方案,但想知道我们是否可以不使用它。

提前致谢!

1 个答案:

答案 0 :(得分:4)

这仅适用于使用已知的有限功能签名集合进行操作,例如

public static <T,U,R> R withRecording(BiFunction<T,U,R> func, T arg1, U arg2) {
    R response = func.apply(arg1, arg2);
    // Record arg1, arg2 and the response
    return response;
}

可用作

SomeReturn retVal = withRecording(someObject::doSomething, arg1, arg2);

这不仅暗示您必须为每个支持的签名创建一个重载,即不同数量的参数,您还必须为每个具有两个以上参数的函数创建适当的接口,因为没有预定义的接口这些案件。

此外,请注意,函数对象本身不会显示有关实际函数的任何内容,因此您要记录的是某些函数已使用特定参数和结果调用,但不是功能...

更好的解决方案是将doSomething声明为接口方法,允许将someObject替换为对另一个实现的引用,该实现委托给someObject并记录所有调用。可以使用代理以一般方式实现此功能,但是, 与AOP解决方案重叠......