English 中文(简体)
与泽西岛有关的依赖性注射
原标题:Dependency Injection with Jersey

如果我使用泽西1.12,我拥有多个资源类别,他们都需要获得某种共同的环境, 注射依赖性的最佳方法是什么,不管是在资源类的构建器中,还是在处理器方法中?我需要使用外部的DI图书馆,还是泽西有内在的东西?

即Foos的资源可能是这样的:

package com.example.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/some/api/path/foo")
public class FooResource
{
    @GET
    @Produces("text/html")
    public String getFoo(@QueryParam("id") String id)
    {
        Foo foo = /* get a Foo from some shared context based on id */
        /* Process foo into a String */
    }
}

" 栏杆 " :

package com.example.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/some/api/path/bar")
public class BarResource
{
    @GET
    @Produces("text/html")
    public String getBar(@QueryParam("id") String id)
    {
        Bar bar = /* get a Bar from some shared context based on id */
        /* Process bar into a String */
    }
}
最佳回答

我最后使用Google Guice(Google Guice),这是一个轻量级的DI框架,它与泽西岛融合得很好。

首先,我加上了pom.xml的依附关系:

    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>3.0</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-guice</artifactId>
        <version>1.12</version>
        <scope>compile</scope>
    </dependency>

我想要一个DAO 以一个有接口的单子执行:

public interface MySingletonDao
{
    // ... methods go here ...
}

并具体落实:

@Singleton
public class ConcreteMySingletonDao implements MySingletonDao
{
    // ... methods go here ...
}

将资源类别装饰成这样:

@Path("/some/path")
@RequestScoped
public class MyResource
{
    private final MySingletonDao mySingletonDao;

    @Inject
    public MyResource(MySingletonDao mySingletonDao)
    {
        this.mySingletonDao = mySingletonDao;
    }

    @POST
    @Produces("application/json")
    public String post() throws Exception
    {
            // ... implementation goes here ...
    }
}

创建了一个要执行绑定的类 :

public class GuiceConfig extends GuiceServletContextListener
{
    @Override
    protected Injector getInjector()
    {
        return Guice.createInjector(new JerseyServletModule()
        {
            @Override
            protected void configureServlets()
            {
                bind(MyResource.class);
                bind(AnotherResource.class);
                bind(MySingletonDao.class).to(ConcreteMySingletonDao.class);
                serve("/*").with(GuiceContainer.class);
            }
        });
    }
}

我用Jetty而不是玻璃鱼来充当服务器。在我的功能测试中,这看起来像:

private void startServer() throws Exception
{
    this.server = new Server(8080);
    ServletContextHandler root =
        new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);

    root.addEventListener(new GuiceConfig());
    root.addFilter(GuiceFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
    root.addServlet(EmptyServlet.class, "/*");

    this.server.start();
}

EmptyServlet 来自Sunny Gleason的样本代码,作为答复在以下网站提供:https://stackoverflow.com/a/3296467>> -- -- 我最初的回答是:

root.addServlet(new ServletHolder(new ServletContainer(new PackagesResourceConfig("com.example.resource"))), "/*");

代替行

root.addServlet(EmptyServlet.class, "/*");

但这使得泽西岛尝试和进行 依赖性注射 而不是Guice, 这导致了运行时间错误。

问题回答

单子注射器:http://jersey.java.net/nonav/apidocs/1.12/jersey/com/sun/jersey/spi/inject/SingletonTypeimitableProvider.html

样本 :

ResourceConfig resourceConfig = new DefaultResourceConfig();
resourceConfig.getSingletons().add(
        new SingletonTypeInjectableProvider<Context, SingletonType>(
               SingletonType.class, new SingletonType()) {});{code}

或者,您可以创建单顿 - ype 注射性孕育者子孙, 用 @ Provider 添加它作为一个类。 您可以在您需要的地方和标准泽西岛注射启动的地方, 输入您提供的例子 。

有一个支持春季依赖性注射的球衣春季弹簧项目。 用 Spring Serverlet 替换您的球衣服务集装箱, 在 Web. xml 上添加一个背景 Loader 听器, 您可以将豆子输入到您的组件中。 这里的设置有一个相当不错的通道 。

http://www.mkyong.com/webservices/jax-rs/jersey-spring-comminter-example/

编辑 编辑 编辑 编辑 编辑 编辑

在此设置一个不需要添加任何依赖关系的想法 。 创建您自己的 SerletCtext 倾听器, 将您的对象添加到 SerletContext 中。 然后将 SerletCtext 注入到您的资源中

public class MyContextListener implements ServletContextListener
{

    @Override
    public void contextDestroyed(ServletContextEvent event)
    {
    }

    @Override
    public void contextInitialized(ServletContextEvent event)
    {
        ServletContext context = event.getServletContext();
        context.setAttribute(Foo.class.getName(), new FooImpl());
    }

}

然后,在你的资源中,

@Path("blah")
public class MyResource 
{
   private Foo foo;

   public MyResource(@Context ServletContext context)
   {
      foo = (Foo) context.getAttribute(Foo.class.getName());
   } 
}

你不必使用外部图书馆,除非你愿意这样做。 有大量文件证明,让土发委会正确与泽西岛合作目前是一个痛苦。 然而,我从经验中可以说,可以自己完成这项工作。 一段时间以来,我跳过那些环圈,但我似乎记得我们不得不让资源无国籍的EJBs去工作。 我本可以采取其他步骤,但现在我不记得了那些步骤。

当泽西2.0出现的时候,这应该更容易得多,因为他们会转而使用CDI核心实施,而不是他们自己的实施。

http://java.net/jira/browse/JERSEY-517" rel=“nofollow>http://java.net/jira/browse/JERSEY-517





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签