【问题标题】:Invoke an interface default method on a proxy在代理上调用接口默认方法
【发布时间】:2018-03-22 10:27:00
【问题描述】:

如何创建代理并调用默认接口方法,就好像它们是由代理超类实现的一样?例如:

interface Foo {

    default int returnSomething() {
        return 1;
    }

}

interface Bar extends Foo {

    default int returnSomethingMore() {
        return returnSomething();
    }

}

class Super implements Foo {

    @Override
    public int returnSomething() {
        return 2;
    }

}

我需要一个Bar 的代理,它在调用Bar::returnSomethingMore 时将使用Super::returnSomething 实现。

我试过了:

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Super.class);
enhancer.setInterfaces(new Class[] { Bar.class });
enhancer.setCallback((obj, method, args, proxy) -> {
    if (method.getName().equals("returnSomethingMore")) {

        return proxy.invokeSuper(obj, args);
        // -> NoSuchMethodError

        return proxy.invoke(obj, args);
        // -> StackOverflowError

        Class<?> declaringClass = method.getDeclaringClass();
        Lookup lookup = MethodHandles.lookup();
        return MethodHandles
                .privateLookupIn(declaringClass, lookup)
                .unreflectSpecial(method, declaringClass)
                .bindTo(obj)
                .invokeWithArguments(args);
        // -> returns 1, not 2
    }
});

如何创建returnSomethingMore 方法返回2 的代理对象?

【问题讨论】:

  • 基本上,我需要的是避免代理某些方法,即让代理实例自己调用默认实现。但我在Enhancer 上看到的唯一“过滤”是callbackFilter,它让您选择使用哪个 回调,而不是避免 使用一个。跨度>
  • 还尝试为该方法使用NoOp 回调过滤器,然后它仍然返回1 而不是2(例如,它不使用returnSomethingSuper 实现)。

标签: java cglib dynamic-proxy


【解决方案1】:

我已经放弃了 cglib(感谢 SO 的标签,我知道它不再处于积极开发中)并采用了 ByteBuddy,它为我提供了我所需要的代理:

@Test
public void defaultInterfaceMethodTest() {
    Class<? extends Super> loaded = new ByteBuddy()
            .subclass(Super.class)
            .implement(Bar.class).make()
            .load(this.getClass().getClassLoader()).getLoaded();
    Bar newInstance = (Bar) loaded.getConstructor().newInstance();
    int shouldBeTwo = newInstance.returnSomethingMore();
    Assert.assertEquals(2, shouldBeTwo);
}

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多