Package ratpack.guice

Class Guice


  • public abstract class Guice
    extends Object
    Static utility methods for creating Google Guice based Ratpack infrastructure.

    Any non trivial application will require supporting objects for the handler implementations, for persistence for example. These supporting objects can be managed by Guice and made available to handlers (either by dependency injection or registry lookup) for increased reusability, modularity and testability.

    The Guice integration is not part of the Ratpack core library, but is available as a separate add on. That said, Ratpack is designed to support something like Guice as an integral piece via it's Registry abstraction. Guice is the “official” solution.

    Starting a Guice Ratpack app

    Below is a complete example for bootstrapping a Guice based Ratpack application.

    
     import com.google.inject.AbstractModule;
     import ratpack.guice.Guice;
     import ratpack.core.handling.Context;
     import ratpack.core.handling.Handler;
     import ratpack.test.embed.EmbeddedApp;
    
     import javax.inject.Inject;
     import javax.inject.Singleton;
    
     import static org.junit.jupiter.api.Assertions.*;
    
     public class Example {
    
       static class SomeService {
         private final String value;
    
         SomeService(String value) {
           this.value = value;
         }
    
         public String getValue() {
           return value;
         }
       }
    
       static class SomeOtherService {
         private final String value;
    
         SomeOtherService(String value) {
           this.value = value;
         }
    
         public String getValue() {
           return value;
         }
       }
    
       public static class ServiceModule extends AbstractModule {
         protected void configure() {
           bind(SomeService.class).toInstance(new SomeService("foo"));
           bind(SomeOtherService.class).toInstance(new SomeOtherService("bar"));
           bind(InjectedHandler.class);
         }
       }
    
       @Singleton
       static class InjectedHandler implements Handler {
         private final SomeService service;
    
         @Inject
         public InjectedHandler(SomeService service) {
           this.service = service;
         }
    
         public void handle(Context ctx) {
           ctx.render(service.getValue() + "-" + ctx.get(SomeOtherService.class).getValue());
         }
       }
    
       public static void main(String... args) throws Exception {
         EmbeddedApp.of(s -> s
           .registry(Guice.registry(b -> b.module(ServiceModule.class)))
           .handlers(chain -> {
             // The registry in a Guice backed chain can be used to retrieve objects that were bound,
             // or to create objects that are bound “just-in-time”.
             chain.get("some/path", InjectedHandler.class);
           })
         ).test(httpClient -> {
           assertEquals("foo-bar", httpClient.get("some/path").getBody().getText());
         });
       }
    
     }
     

    Accessing Guice bound objects in Handlers

    There are two ways to use Guice bound objects in your handler implementations.

    Dependency Injected Handlers

    The handler() methods used to create a Guice backed application take an Action that operates on a Chain instance. This chain instance given to this action provides a Guice backed Registry via its Chain.getRegistry() method. This registry is able to retrieve objects that were explicitly bound (i.e. defined by a module), and bind objects “just in time”. This means that it can be used to construct dependency injected Handler implementations.

    Simply pass the class of the handler implementation to create a new dependency injected instance of to this method, then add it to the chain.

    See the code above for an example of this.

    Accessing dependencies via context registry lookup

    The Context object that is given to a handler's Handler.handle(Context) method is also a registry implementation. In a Guice backed app, Guice bound objects can be retrieved via the Registry.get(Class) method of the context. You can retrieve any bound object via its publicly bound type.

    However, this will not create “just-in-time” bindings. Only objects that were explicitly bound can be retrieved this way.

    Guice modules as Ratpack “plugins”.

    Add on Ratpack functionality is typically provided via Guice modules. For example, the Jackson integration for JSON serialisation is provided by the ratpack-jackson add-on which ships a Guice module. To use its functionality simply register the module it provides with the BindingsSpec used to bootstrap the application.

    Groovy Applications

    The Ratpack Groovy add-on provides application modes that automatically incorporate Guice (namely the “Ratpack Script” mode). The module registration process is simpler and more convenient in this mode, and there are additional options for obtaining Guice bound objects.

    See the Groovy add-on's documentation for more details.

    • Method Detail

      • registry

        public static Registry registry​(com.google.inject.Injector injector)
        Creates a Ratpack Registry backed by the given Injector that will NOT create objects via “just-in-time” binding.
        Parameters:
        injector - The injector to back the registry
        Returns:
        A registry that wraps the injector
      • newInjectorFactory

        public static Function<com.google.inject.Module,​com.google.inject.Injector> newInjectorFactory​(ServerConfig serverConfig)