让hk2和Jersey注入课程

时间:2018-03-16 19:12:59

标签: java dependency-injection jersey hk2

如何在没有一对一创建和注册工厂的情况下让Jersey注入课程?

我有以下配置:

public class MyConfig extends ResourceConfig {
    public MyConfig() {
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(FooFactory.class).to(Foo.class);
                bindFactory(BazFactory.class).to(Baz.class);
            }
        });
    }
}

hk2现在将成功注入Foo和Baz:

// this works; Foo is created by the registered FooFactory and injected
@GET
@Path("test")
@Produces("application/json")
public Response getTest(@Context Foo foo) {
    // code
}

但这不是我的目标。我的目标是注入包装这些类的对象。有很多,它们各自消耗Foo和Baz的不同组合。一些例子:

public class FooExtender implements WrapperInterface {

    public FooExtender(Foo foo) {
        // code
    }
}

public class FooBazExtender implements WrapperInterface {

    public FooBazExtender(Foo foo, Baz baz) {
        // code
    }
}

public class TestExtender implements WrapperInterface {

    public TestExtender(Foo foo) {
        // code
    }
    // code
}

等等。

以下不起作用:

// this does not work
@GET
@Path("test")
@Produces("application/json")
public Response getTest(@Context TestExtender test) {
    // code
}

我可以为每个人创建一个工厂,并使用bindFactory语法在我的应用程序配置类中注册它,就像我在Foo和Baz中所做的那样。但由于有问题的对象数量,这不是一个好方法。

我已阅读了很多hk2文档,并尝试了各种方法。我只是不知道hk2究竟是如何工作来得出答案的,而且似乎是一个普遍的问题,应该有一个简单的解决方案。

2 个答案:

答案 0 :(得分:2)

实际上只需要更复杂的初始化工厂。如果您不需要,您需要做的就是绑定服务

#include <list>


int main()
{
    std::list<int> list;
    for (int x = 0; x < 20; x++)
    {
        list.push_back(x);
    }
    for (auto iter = list.begin(); iter != list.end(); ++iter)
    {
        if (*iter % 2)
        {
            list.erase(iter);
        }
    }
}

您还需要在构造函数上添加std::list,以便HK2知道注入@Override protected void configure() { // bind service and advertise it as itself in a per lookup scope bindAsContract(TestExtender.class); // or bind service as a singleton bindAsContract(TestExtender.class).in(Singleton.class); // or bind the service and advertise as an interface bind(TestExtender.class).to(ITestExtender.class); // or bind the service and advertise as interface in a scope bind(TestExtender.class).to(ITestExtender.class).in(RequestScoped.class); } @Inject

Foo

答案 1 :(得分:0)

我最后使用FastClasspathScanner从我感兴趣的包中获取类。然后我分批调用了适当的绑定方法(bindAsContractbind),如在Paul Samsotha's answer中提到(在添加适当的@Inject注释之后)。

这似乎是最有效的方法,可以模拟自动扫描,避免手动注册每个类。

感觉就像一个黑客,如果hk2没有更好的方法,我会感到惊讶。