Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capability can't find correct enrich method #2237

Open
JamieYoungYang opened this issue Nov 19, 2023 · 5 comments
Open

Capability can't find correct enrich method #2237

JamieYoungYang opened this issue Nov 19, 2023 · 5 comments

Comments

@JamieYoungYang
Copy link

JamieYoungYang commented Nov 19, 2023

test-code:
public class CapabilityInvokeTest {

static class TestCapability implements Capability {
public Father enrich(Father father) {
father.balance = 10;
return father;
}
public Son enrich(Son son) {
son.balance = 5;
return son;
}
}

static class Father {
    int balance;
}

static class Son extends Father {
}

public static void main(String[] args) {
    Son son = new Son();
    Father father = new Father();
    // enrich Son
    Capability.invoke(son, new TestCapability(), Son.class);
    System.out.println(son.balance); // 10
    // enrich Father
    Capability.invoke(father, new TestCapability(), Father.class);
    System.out.println(father.balance); // 10
}

}

**reason:**Capability.invoke method
Arrays.stream(capability.getClass().getMethods())
.filter(method -> method.getName().equals("enrich"))
.filter(method -> method.getReturnType().isAssignableFrom(capabilityToEnrich))
.findFirst()

problem:
.filter(method -> method.getReturnType().isAssignableFrom(capabilityToEnrich)).findFirst()

Father.class.isAssignableFrom(Son.class)
Son.class.isAssignableFrom(Son.class)
both return true,so findFirst allways return the first method For Father.enrich

There seem to be two ways to solve this problem
first: adjust the order in which methods are defined,defind the Son.enrich before the Father.enrich
second: .filter(method -> method.getReturnType() == capabilityToEnrich)

@velo
Copy link
Member

velo commented Nov 19, 2023

Hrmmm, ok, how are you finding this issue with feign classes?

@JamieYoungYang
Copy link
Author

Hrmmm, ok, how are you finding this issue with feign classes?

When I was learning the source code of feign, I accidentally found it, I think it seems to be a bug, so I went to verify my idea

@velo
Copy link
Member

velo commented Nov 19, 2023

Sure, a pull request is welcome.

@JamieYoungYang
Copy link
Author

Sure, a pull request is welcome.

ok, my pleasure

@JamieYoungYang
Copy link
Author

JamieYoungYang commented Nov 20, 2023

Sure, a pull request is welcome.

While Capability mainly enriches the Feign base components, I would like to mention that it still allows enhancements to custom components, which can be a problem if the developer is not careful。
Thanks for your patience!

public static class TestFeign {
public static Builder builder() {
return new Builder();
}

    public static final class Builder extends Feign.Builder {
        private final Father father = new Father.Default();
        private final Son son = new Son.Default();

        public Builder addCapability(Capability capability) {
            return (Builder)super.addCapability(capability);
        }

        public Father getFather() {
            return father;
        }

        public Son getSon() {
            return son;
        }
    }

}

public static class FamilyCapability implements Capability {
    public Father enrich(Father father) {
        father.add(10);
        return father;
    }

    public Son enrich(Son son) {
        son.add(5);
        return son;
    }
}

public interface Father {
    void add(int money);
    int getBalance();

    class Default implements Father{
        private int balance;
        @Override
        public void add(int money) {
            this.balance += money;
        }

        @Override
        public int getBalance() {
            return balance;
        }

    }
}

public interface Son extends Father {
    class Default implements Son{
        private int balance;
        @Override
        public void add(int money) {
            this.balance += money;
        }

        @Override
        public int getBalance() {
            return balance;
        }
    }
}

interface TestTarget{

}
@Test
public void enrichTest() {
    TestFeign.Builder builder = TestFeign.builder().addCapability(new FamilyCapability());
    TestTarget target = builder.target(TestTarget.class, "https://github.com/");
    System.out.println(builder.getFather().getBalance()); // 10
    System.out.println(builder.getSon().getBalance()); // 10
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants