Comment activer CDI inject dans le service Web (jaxrs / jersey) sur java se courir grizzly?

Comment autoriser l’injection de ressources CDI dans des ressources de service Web reposantes? J’utilise java standard à l’aide de la soudure 2 (cdi), du jersey (jaxrs) et du grizzly (serveur Web). Voici ma ressource Web simple:

import training.student.StudentRepository; import javax.inject.Inject; import javax.ws.rs.*; @Path("student") public class StudentWebResource { @Inject private StudentRepository studentRepository; @GET @Path("count") @Produces(MediaType.TEXT_PLAIN) public Integer getCount() { return studentRepository.studentCount(); } } 

Et voici comment j’ai soudé le démarrage de mon simple serveur Web:

 public class Main { public static void main(Ssortingng[] args) throws Exception { startCdiApplication(); } public static void startCdiApplication() throws Exception { Weld weld = new Weld(); try { WeldContainer container = weld.initialize(); Application application = container.instance().select(WebServer.class).get(); application.run(); } finally { weld.shutdown(); } } } 

Et le code que je soupçonne devra être modifié pour informer le maillot d’utiliser la soudure pour la résolution d’injection CDI:

 ... import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; public class WebServer implements Application { /* * startup the grizzly http server to make available the restful web services */ private void startWebServer() throws IOException, InterruptedException { final ResourceConfig resourceConfig = new ResourceConfig().packages("training.webservice").register(new JacksonFeature()); final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(getBaseUri(), resourceConfig); server.start(); Thread.currentThread().join(); } ... @Override public void run() throws IOException, InterruptedException { startWebServer(); } } 

Après avoir vu ce post stackoverflow , j’ai mis en œuvre la solution suivante. Je ne sais pas si c’est la meilleure voie à prendre, mais cela a fonctionné.

J’ai créé un classeur hk2 et enregistré le classeur:

 public class WebServiceBinder extends AbstractBinder { @Override protected void configure() { BeanManager bm = getBeanManager(); bind(getBean(bm, StudentRepository.class)) .to(StudentRepository.class); } private BeanManager getBeanManager() { // is there a better way to get the bean manager? return new Weld().getBeanManager(); } private  T getBean(BeanManager bm, Class clazz) { Bean bean = (Bean) bm.getBeans(clazz).iterator().next(); CreationalContext ctx = bm.createCreationalContext(bean); return (T) bm.getReference(bean, clazz, ctx); } } 

Puis modifié l’instanciation ResourceConfig d’en haut pour:

 final ResourceConfig resourceConfig = new ResourceConfig() .packages("training.webservice") .register(new JacksonFeature()) .register(new WebServiceBinder()); 

La réponse sélectionnée date d’un certain temps. Il n’est pas pratique de déclarer chaque liaison dans un classeur HK2 personnalisé. Je devais juste append une dépendance. Même s’il a été conçu pour Glassfish, il s’intègre parfaitement dans d’autres conteneurs. J’utilise Tomcat / Grizzly.

   org.glassfish.jersey.containers.glassfish jersey-gf-cdi 2.14  

Voici un exemple avec JerseyTest (même principe si vous l’exécutez à partir d’une méthode principale). Il me suffisait de déclarer une dépendance vis-à-vis de la soudure et de déclarer un conteneur Weld avant d’instancier mes ressources – comme vous l’avez également fait – et cela fonctionne immédiatement.

 public class GrizzlyTest extends JerseyTest { private Weld weld; private WeldContainer container; @Override protected Application configure() { weld = new Weld(); container = weld.initialize(); return new ResourceConfig(MyResource.class); } @Test public void test() { System.out.println(target("myresource").request().get(Ssortingng.class)); } @After public void after() { weld.shutdown(); } } 

Depuis au moins Weld 2.2.0.Final, il n’est pas nécessaire de s’embrouiller avec HK2 Binder.

Comme le stipule la documentation officielle de Weld, il vous suffit de vous inscrire org.jboss.weld.environment.servlet.Listener . Code extrait de la doc:

 public class Main { public static void main(Ssortingng[] args) throws ServletException, LifecycleException { Tomcat tomcat = new Tomcat(); Context ctx = tomcat.addContext("/", new File("src/main/resources").getAbsolutePath()); Tomcat.addServlet(ctx, "hello", HelloWorldServlet.class.getName()); ctx.addServletMapping("/*", "hello"); ctx.addApplicationListener(Listener.class.getName()); tomcat.start(); tomcat.getServer().await(); } public static class HelloWorldServlet extends HttpServlet { @Inject private BeanManager manager; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain"); resp.getWriter().append("Hello from " + manager); } } } 

L’écouteur de servlet ci-dessus gère l’ ensemble du cycle de vie du conteneur Weld. Donc, il n’est pas nécessaire de:

  Weld weld = new Weld(); WeldContainer container = weld.initialize(); 

UPDATE Comme @EdMelo l’a souligné, le serveur HTTP Grizzly n’est pas un conteneur de servlets totalement conforme. Je ne le savais pas, merci pour cet indice. Donc, je ne suis pas sûr si ma réponse s’applique toujours ici.