Guice

Note

It is important to say that guicey did not apply any "guice magic". Guicey just register additional bindings, which you can use in your beans.

Or you can simply enable full guice report (.printAllGuiceBindings()) and see all added bindings under GuiceBootsrapModule:

 7 MODULES with 106 bindings
    │   
    └── GuiceBootstrapModule         (r.v.d.guice.module)       
        ├── <scope>              [@Prototype]     -                                               at ru.vyarus.dropwizard.guice.module.GuiceBootstrapModule.configure(GuiceBootstrapModule.java:51)
        ├── instance             [@Singleton]     Options                                         at ru.vyarus.dropwizard.guice.module.GuiceBootstrapModule.configure(GuiceBootstrapModule.java:57)
        ├── instance             [@Singleton]     ConfigurationInfo                               at ru.vyarus.dropwizard.guice.module.GuiceBootstrapModule.configure(GuiceBootstrapModule.java:60)
        ...

Added bindings

All applied bindings are described in the user guide.

Main objects:

  • io.dropwizard.setup.Bootstrap
  • io.dropwizard.Configuration
  • io.dropwizard.setup.Environment

Bindings below are not immediately available as HK2 context starts after guice:

  • javax.ws.rs.core.Application
  • javax.ws.rs.ext.Providers
  • org.glassfish.hk2.api.ServiceLocator
  • org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractorProvider

Request-scoped bindings:

  • javax.ws.rs.core.UriInfo
  • javax.ws.rs.container.ResourceInfo
  • javax.ws.rs.core.HttpHeaders
  • javax.ws.rs.core.SecurityContext
  • javax.ws.rs.core.Request
  • org.glassfish.jersey.server.ContainerRequest
  • org.glassfish.jersey.server.internal.process.AsyncContext
  • javax.servlet.http.HttpServletRequest
  • javax.servlet.http.HttpServletResponse

Request scoped objects must be used through provider:

@Inject Provider<HttpServletRequest> requestProvider;

Warning

Pay attention that inside rest resources @Context injection on fields will not work on fields, but will for method arguments.

Configuration bindings

It is quite common need to access configuration value by path, instead of using entire configuration object. Often this removes boilerplate when one option is used in multiple places, compare:

@Inject MyConfiguration config
...

// in each usage
config.getSub().getFoo()

and

@Inject @Config("sub.foo") String foo;

// and use direct value in all places

Also, often you have some unique configuration sub object, e.g.

public class MyConfig extends Configuration {
    @JsonProperty
    AuthConfig auth;
}

It may be more convenient to bind it directly, instead of full configuration:

@Inject @Config AuthConfig auth;

See complete description in the user guide

Warning

If not disabled, guicey will always bind all configuration values (including values from base Configuration class). Don't be confused when use custom config report - it just not shows common bindings for simplicity, but they are still applied.

Note

Use configuration bindings report to see available configuration bindings. It is executed before injector creation and so could be used for problems diagnosis. Bindings may change with configuration values changes (e.g. server section depends on server implementation used).

Extensions and AOP

As it was mentioned guice knows about extensions either by classpath scan search, manual declaration or guice bindings.

Recognition from guice binding is not interesting as you bind it manually.

Auto scan and manual declaration are essentially the same: guicey have extension class, which must be bound to guice context. In most cases it would be just bind(Extension.class) (but some installers can do more sophisticated bindings, like plugins installer).

As you can see, in all cases extension is constructed by guice and so AOP features will work.

Note

While HK2 is still used, instance management may be delegated to HK2 but it is not used in core guicey (just an ability; this is almost never required)

All extensions recognized from guice bindings are clearly visible in the configuration report.

Servlets and filters

GuiceFilter is registered on both main and admin contexts. Guice servlets and filters (registered through ServletModule) may co-exist with pure servlets and filters: as guice filter intercept both contexts, it would be able to manage request scope for all calls (even rest).

When you register servlets and filters directly, their instances will be managed by guice (because they are extensions), just dispatching will work a bit differently, which is almost never important.

As you can see, in case of servlets, AOP features will also be always available. Moreover, scopes will work as expected.

Note

Web report could show actual mapping difference between pure servlets and GuiceFilter-managed servlets.

Startup

The only not intuitive step, performed by guicey, is modules analysis: just before injector creation guicey parse all registered modules (using guice SPI):

List<Element> elements = Elements.getElements(modules)

Note

Pay attention that guicey looks only actual bindings before injector creation. And that's why it would not "see" JIT bindings (bindings that was not declared and created just because guice found an injection point). This is intentional to force declaration of all important bindings.

To avoid re-parsing elements during injector creation, guicey pack all parsed elements as module with:

Module module = Elements.getModule(elements)

And so guicey injector factory will receive this synthetic module. So if you need access to raw module, you can either do it with event or disable modules analysis (but in this case some features would not work)

Note

Guice bindings override (Modules.override()), available through guicey api modulesOverride(), will also cause syntetic module (because overrides are applied before calling injector factory). But this supposed to be used for tests only (just to mention).

AOP

Not guicey-related, but still, as it's not always obvious how AOP is applied on beans use AOP report - it shows all affected beans and (more importantly) applied aop handlers order.