简体   繁体   English

HK2相当于@Provides的Guice for Jersey 2

[英]HK2 equivalent of @Provides in Guice for Jersey 2

I've been using Jersey 1.X with Google Guice for dependency injection. 我一直在使用Jersey 1.X和Google Guice进行依赖项注入。 Switching to Jersey 2.X seems to mean you need to use HK2 for dependency injection instead, I'm struggling to find a few things that I had in Guice. 切换到Jersey 2.X似乎意味着您需要使用HK2进行依赖项注入,我正在努力寻找Guice中的一些功能。

In Jersey 1.X with Guice, I would have something like this for the application: 在带有Guice的Jersey 1.X中,对于该应用程序,我将具有以下内容:

public class GuiceServletTestConfig extends GuiceServletContextListener  {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule(){
            @Override
            protected  void configureServlets(){
                bind(MyResource.class);
                serve("/*").with(GuiceContainer.class);
                bind(MyDAO.class).to(MyDAOSQL.class)
            }
        });
    }
}

And something like this for tests: 像这样的测试:

public class GuiceServletTestConfig extends GuiceServletContextListener  {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule(){
            @Override
            protected  void configureServlets(){
                bind(MyResource.class);
                serve("/*").with(GuiceContainer.class);
            }

            @Provides
            MyDAO provideMockMyDAO(){
                MyDAO dao = mock(MyDAO.class);
                return dao;
            }
        });
    }
}

Any my resrouce would look like this: 我的所有资源看起来都像这样:

@Path("myresource")
public class MyResource {
    private MyDAO myDAO;

    @Inject
    protected void setMyDAO(MyDAO myDAO) {
        this.myDAO = myDAO;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response get() {
        // Do something with myDAO
        // Return response    
    }
}

That was I can define mocks for my tests and everything is good. 那是我可以为测试定义模拟,一切都很好。

With Jersey 2.X however, I cannot find any equivalent for the @Provides annotation. 但是,对于Jersey 2.X,我找不到@Provides注释的等效项。 MyResource is effectively the same. MyResource实际上是相同的。 For dependency injection for the real application, I have: 对于实际应用程序的依赖项注入,我有:

public class Application extends ResourceConfig {
    public Application() {
        packages("com.my.package.resources");

        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(MyDAOSQL.class).to(MyDAO.class);
            }
        });
    }
}

But I don't know how to provide mocks for tests. 但是我不知道如何为测试提供模拟。 Anyone knoe how? 有人知道如何?

HK2 allows you to bind Factories that work just like @Provides. HK2允许您绑定像@Provides一样工作的工厂。 Here is the javadoc . 这是javadoc I do think it isn't as convenient since you have to create a class that implements Factory. 我确实认为这样做不方便,因为您必须创建一个实现Factory的类。 I may add an enhancement Jira to do a CDI style @Produces. 我可能会添加一个增强型Jira以使用CDI样式@Produces。

Also, you can continue to use Guice in Jersey (many people do) by using the Guice-HK2 bridge . 另外,您可以通过使用Guice-HK2桥继续在泽西岛使用Guice(很多人都这样做)。 There are some limitations when using the Bridge (like having to use @HK2Inject for classes created by Guice but to be injected with HK2 services), but most things do still work. 使用Bridge时有一些限制(例如必须对Guice创建的类使用@ HK2Inject,但要使用HK2服务进行注入),但是大多数事情仍然可以进行。

OK, so I figured out a way that works for me. 好的,所以我想出了一种对我有用的方法。 One thing that threw me off was the swapping of the bind().to() from Guice to HK2. 让我失望的一件事是将bind().to()从Guice交换到HK2。 In Guice, you write: 在Guice中,您写道:

bind(Abstract.class).to(Concrete.class)

Where as in HK2, you write: 如在HK2中,您写道:

bind(Concrete.class).to(Abstract.class)

The way to get the provides behaviour can be achieved with the following code: 可以通过下面的代码来实现获取提供行为的方法:

public class MyResourceIT extends JerseyTest {
    @Override
    protected Application configure() {
        ResourceConfig resourceConfig = new ResourceConfig();
        resourceConfig.register(MyResource.class);

        resourceConfig.register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(provideMyDaoMock()).to(MyDao.class);
            }

            private MyDao provideMyDaoMock() {
                MyDao myDaoMock = mock(MyDao.class);
                return myDaoMock;
            }
        });
        return resourceConfig;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM