112 votes

L'injection de dépendance avec Jersey 2.0

À partir de zéro sans précédent Jersey 1.x de connaissances, je vais avoir un moment difficile de comprendre comment le programme d'installation d'injection de dépendance dans mon Maillot 2.0 projet.

Je comprends aussi que HK2 est disponible en Jersey 2.0, mais je n'arrive pas à trouver des docs qui aident avec le Maillot 2.0 intégration.

@ManagedBean
@Path("myresource")
public class MyResource {

    @Inject
    MyService myService;

    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/getit")
    public String getIt() {
        return "Got it {" + myService + "}";
    }
}

@Resource
@ManagedBean
public class MyService {
    void serviceCall() {
        System.out.print("Service calls");
    }
}

pom.xml

<properties>
    <jersey.version>2.0-rc1</jersey.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>${jersey.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-common</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey</groupId>
        <artifactId>jax-rs-ri</artifactId>
    </dependency>
</dependencies>

Je peux obtenir le conteneur de début et de servir de mes ressources, mais dès que j'ai ajouter @Inject pour MyService, le cadre déclenche une exception:

SEVERE: Servlet.service() for servlet [com.noip.MyApplication] in context with path [/jaxrs] threw exception [A MultiException has 3 exceptions.  They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.noip.MyResource errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.noip.MyResource
] with root cause
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=MyService,parent=MyResource,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1039471128)
    at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)


Mon starter projet est disponible sur GitHub: https://github.com/donaldjarmstrong/jaxrs

111voto

joscarsson Points 1567

Vous devez définir une AbstractBinder , et de l'inscrire dans votre JAX-RS de l'application. Le classeur spécifie comment l'injection de dépendance devrait créer vos classes.

public class MyApplicationBinder extends AbstractBinder {
    @Override
    protected void configure() {
        bind(MyService.class).to(MyService.class);
    }
}

Lors de l' @Inject est détecté sur un paramètre ou d'un champ de type MyService.class il est instancié en utilisant la classe MyService. Pour utiliser ce classeur, il faut être inscrit auprès de JAX-RS de l'application. Dans votre web.xml, de définir un JAX-RS application comme ceci:

<servlet>
  <servlet-name>MyApplication</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.mypackage.MyApplication</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>MyApplication</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

Mettre en œuvre l' MyApplication classe (indiquée ci-dessus dans l' init-param).

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        register(new MyApplicationBinder());
        packages(true, "com.mypackage.rest");
    }
}

Le liant de la spécification de l'injection de dépendance est enregistré dans le constructeur de la classe, et nous avons aussi dire à l'application où trouver le RESTE des ressources (dans votre cas, MyResource) à l'aide de l' packages() appel de la méthode.

3voto

Benjamin Mesing Points 131

Oracle recommande d'ajouter le @Path annotation à tous les types de être injecté lors de la combinaison de JAX-RS avec le CDI: http://docs.oracle.com/javaee/7/tutorial/doc/jaxrs-advanced004.htm Mais c'est loin d'être parfait (par exemple, vous obtiendrez avertissement de Jersey au démarrage), j'ai décidé de prendre cette route, qui me permet de gagner de la maintenance de tous les types pris en charge dans un classeur.

Exemple:

@Singleton
@Path("singleton-configuration-service")
public class ConfigurationService {
  .. 
}

@Path("my-path")
class MyProvider {
  @Inject ConfigurationService _configuration;

  @GET
  public Object get() {..}
}

0voto

Choi Points 39

Si vous préférez utiliser Guice et vous ne voulez pas de déclarer toutes les liaisons, vous pouvez également essayer cette carte:

guice-pont-jit-injecteur

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X