Search code examples
javajerseyguicehk2

Why should i use guice-hk2-bridge?


I'm sorry for the stupid question, but i really searched for an answer for this question and didn't get a clearly one.

I know that jersey uses hk2 as default DI and because hk2 is performance loss, the alternative DI is Guice which is better, we need to configure jersey to use Guice using guice-hk2-bridge.

The question is WHY ?, why we need to configure jersey ?, why we can't just use com.google.inject.Inject instead of javax.inject.Inject, using Guice by importing only the com.google.inject package ?

What is so important about this bridge ?, i tried to work without guice-hk2-bridge and it worked perfectly to me... I'm sure there is something that i misunderstand..

Thanks


Solution

  • I'm not sure how much experience you have programming with annotations, but just to let you know, there is no magic behind them. They are simply metadata, and it is up to the framework to decide what to do with that metadata. For you to say "why can't we switch javax.inject.Inject for com.google.inject.Inject and make Guice work?" shows a lack of understanding of this concept.

    Any DI framework is built around a container to hold all the services bound to that system. For HK2, the container is the ServiceLocator, for Spring, the container is the ApplicationContext, and for Guice, the container is the Injector. That being said, Jersey is tightly coupled with HK21. What this means is that because HK2 is tied to the ServiceLocator container, Jersey is also tied to this ServiceLocator. So when a service is looked up in a Jersey application, it will be looked up via the ServiceLocator. Take for example the following

    @Path("customers")
    public class CustomerResource {
        @Inject
        private CustomerService service;
    
        @GET
        public List<Customer> findAll() {
            return service.findAll();
        }
    }
    

    With the above, somewhere under the hood, the following (in pseudocode) is going on to get the CustomerService to inject into the CustomerResource

    ServiceLocator locator = getServiceLocator();
    CustomerService service = locator.getService(CustomerService.class);
    

    When we have Jersey create (manage the lifecycle of) the resource (the CustomerResource), even the resource is a service bound in the ServiceLocator. This is what I mean that everything in Jersey is tightly coupled with HK2 and the ServiceLocator.

    So in order for us to introduce another DI framework, we need to tap into the ServiceLocator. What the bridge does is tie the Guice Injector to the HK2 ServiceLocator so that the services in the Guice Injector can be discovered through the ServiceLocator. If the CustomerService were a service bound to the Guice Injector, then what would happen is that Jersey would look for it in the ServiceLocator, and the locator would look in the Injector for it. This is wha the bridge does.


    1. Starting version 2.26, Jersey actually breaks ties with the HK2 in being tightly coupled. It's complicated to explain, but in short, we still need to use HK2 with Jersey even though they are no longer tightly coupled.