Search code examples
jerseyjax-rsjersey-2.0hk2

What is the best way to inject a singleton service into a JAX-RS/Jersey resource?


For example, what if several resource endpoints need access to some message bus to handle requests? Surely there is some way to register a singleton service class and inject it into the resources when the service class itself is NOT a resource but used by the resources.
All of the examples I've seen with providers or custom HK2 bindings refer to resources.

The closest thing I found to what I'm looking for was with this question:
Trouble creating a simple singleton class in Jersey 2 using built-in Jersey dependency injection

What is the best JAX-RS/Jersey way of doing this?

Note that the programmatic way would be most useful, I'm not using an xml file to configure the server.


Solution

  • If your platform supports EJB, you could use the @Singleton EJB (javax.ejb package, not javax.inject), and inject it on your resources with the @EJB annotation. Singleton EJB have also outofthebox concurrency access control.

    On plain Jersey, you can use CDI application context. Declare the service class with an @ApplicationScoped annotation and inject it on your resources with @Inject. CDI will only instantiate one bean.

    If you cannot annotate the service class, you can create a method that provides your service implementation an annotate it with @Produces and @ApplicationScoped.

    @Produces
    @ApplicationScoped
    public MyService produceService() {
        // instantiate your service client
    }
    

    And then use it on your resources, with:

    @Inject
    private MyService