Java 在代理上调用接口默认方法

Java 在代理上调用接口默认方法,java,cglib,dynamic-proxy,Java,Cglib,Dynamic Proxy,如何创建代理并调用默认接口方法,就好像它们是由代理超类实现的一样?例如: interface Foo { default int returnSomething() { return 1; } } interface Bar extends Foo { default int returnSomethingMore() { return returnSomething(); } } class Super impleme

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

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
    }
});
Enhancer Enhancer=new Enhancer();
增强器.setSuperclass(Super.class);
setInterfaces(新类[]{Bar.Class});
setCallback((对象、方法、参数、代理)->{
if(method.getName().equals(“returnSomethingMore”)){
返回proxy.invokeSuper(obj,args);
//->NoSuchMethodError
返回proxy.invoke(obj,args);
//->堆栈溢出错误
Class declaringClass=方法.getDeclaringClass();
Lookup Lookup=MethodHandles.Lookup();
返回方法句柄
.privateLookupIn(去极化类,查找)
.无反射特殊(方法,去极化等级)
.bindTo(obj)
.调用参数(args);
//->返回1,而不是2
}
});

我如何创建一个代理对象,它的
returnSomethingMore
方法返回
2

我已经删除了
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);
}
@测试
public void defaultInterfaceMethodTest(){

基本上,我需要的是避免某些方法的代理,即让代理实例自己调用默认实现我在
Enhancer
上看到的是
callbackFilter
,它允许您选择要使用哪个回调,而不是完全避免使用一个。还尝试了该方法的
NoOp
回调过滤器,然后它仍然返回
1
,而不是
2
(例如,它不使用
returnSomething
Super
实现)。