Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
185 views
in Technique[技术] by (71.8m points)

java - HK2 IterableProvider named method not finding Implementation

I have a problem trying to inject a contract with two services bound to it.

I'm using Jersey, and extending ResourceConfig to configure my app, where I'm binding two different implementations (classes FooImpl1 and FooImpl2) to a same contract (interface Foo), ranking them differently. Each of these implementations is annotated with @Named and its name.

In one of my controllers I want to have access to both implementations, so I inject an IterableProvider<Foo> fooProvider.

If I do not specify anything, the implementation with the highest rank is injected always, which is what I want.

The problem appears when I want a concrete implementation, one of them. When I call fooProvider.named( nameOfTheClass ).get(), is returning me null, but if I iterate over the fooProvider, I can have access to both implementations, so they are injected.

Anybody has an idea of what could I be missing?

Thanks a lot for your help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yeah so I'm not sure why it doesn't work with the @Named annotation value, as that's what's stated int the javadoc, but without the need for any annotations, we can configure the name when we do our bindings. We can do so with the named method.

register(new AbstractBinder(){
    @Override
    public void configure() {
        bind(Foo1Impl.class).named("foo1").to(Foo.class);
        bind(Foo2Impl.class).named("foo2").to(Foo.class);
    }
});

UPDATE

So the above solution has been tested. If you are having problems still, post a complete runnable example that demonstrates it not working, like below (which is working)

Interface and Implementations

public interface Greeter {
    String getGreeting(String name);
}

public class EnglishGreeter implements Greeter {
    @Override
    public String getGreeting(String name) {
        return "Hello " + name + "!";
    }
}

public class SpanishGreeter implements Greeter {
    @Override
    public String getGreeting(String name) {
        return "Hola " + name + "!";
    }
}

Resource

@Path("greeting")
public class GreetingResource {
    
    @Inject
    private IterableProvider<Greeter> greeters;
    
    @GET
    public Response getResponse(@QueryParam("lang") String lang,
                                @QueryParam("name") String name) throws Exception {
        
        Greeter greeter = greeters.named(lang).get();
        String message = greeter.getGreeting(name);
        return Response.ok(message).build();
    }
}

Binding. I did it in a Feature, but in a ResourceConfig, it's all the same.

@Provider
public class GreetingFeature implements Feature {
    @Override
    public boolean configure(FeatureContext context) {
        context.register(new AbstractBinder(){
            @Override
            public void configure() {
                bind(EnglishGreeter.class).named("english")
                        .to(Greeter.class).in(Singleton.class);
                bind(SpanishGreeter.class).named("spanish")
                        .to(Greeter.class).in(Singleton.class);
            }
        });
        return true;
    }  
}

Result

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...