Sapphire Gimlets* Robert CooperReachCall.com*no onions
GuiceDependency InjectionJava Source configurationConvention over configurationFast
GinGuice for GWT apps100% Client SideBased on Deferred Binding, so some limitationsFast
Guicevs SpringSpring Config HellPromise of simplicityEver expanding config filesLots of subprojectsBecomes more brittle, in that it becomes harder to extract code for reuse.
Guicevs SpringGuiceJava Source “configuration”Convention over configuration.Annotation basedOpposite of Spring in defaultsPrefer constructor injectionPrefer new instances (“Prototype”) over SingletonsProvider<T> interface encourages mixing scopesType Safe – you got static typing, use it!
Guice 101Basic Annotations@Inject@ImplementedBy/@ProvidedBy@[Scope]@Named
Guice 101public class MyClass {    private final MyService service;    @Injectpublic MyClass(finalMyService service){this.service = service;}    public String sayHelloToUser(){	return this.service.hello();}}   @ImplementedBy(MyServiceImpl.class)public interface MyService {     public String hello();}
Guice 101@Singletonpublic class MyServiceImpl implements MyService {    private final Provider<MySessionObject> sessionProvider;    public MyServiceImpl(final Provider<MySessionObject> sessionProvider){this.sessionProvider = sessionProvider;    }    @Override    public String hello() {        return "Hello, "+sessionProvider.get().getName() +"!";    }}
Guice 101import com.google.inject.servlet.SessionScoped;@SessionScopedpublic class MySessionObject {    private String name;    public String getName(){        return this.name;    }    public void setName(String name){this.name = name;    }}
Guice 101What have we done?MyClass gets a MyService injected.MyService is implemented by MyServiceImpl as a SingletonMyServiceImpl gets a Provider<MySessionObject>The hello() method fetches the Session scoped MySession object, and says Hello!
Guice 101@ImplementedBy provides defaults for any interface (You don’t need to config these if the default is OK)Injection is type safe on constructors (Unit tests have obvious requirements)Scope annotations (@SessionScoped, @Singleton) provide defaults.Provider<T> hides the scope shift from the Singleton service in a single thread method.
Guice 101Making it work on the web…
Guice 101public class GuiceContextListener extends GuiceServletContextListener {    @Override    protected Injector getInjector() {        return Guice.createInjector(            new Module() {               public void configure(Binder binder) {                  // Oh Wait, we don’t need anything here!                }            }         }, new ServletModule() {                @Override                protected void configureServlets() {this.serve(“/myPath/*”).with(MyServlet.class);                }          }    }}
Guice 101Warning! Overly complicated coming up!
Guice 101@Singletonpublic class MyServlet extends HttpServlet{    private final Provider<MySessionObject> sessionProvider;    private final MyClassmyClass;    @Inject    public MyServlet(final Provider<MySessionObject> sessionProvider, MyClassmyClass){this.sessionProvider = sessionProvider;this.myClass = myClass;    }    @Override    public void doGet(HttpServletRequestreq, HttpServletResponse res) throws IOException {this.sessionProvider.get().setName(req.getParameter("name"));res.getWriter().println(myClass.hello());    }}
Guice 101So this is interesting. What happened there?The SessionScoped object was created, and set on the session.MyClass was created one off for injection into the servlet. Since it wasn’t a Provider<MyClass> it was implicitly @Singleton with the servletBut since the MyClass implementation used a provider, it ended up performing a singleton-session scoped op.
Guice 101What else?Servlets, Filters, etc must always be @Singleton of course, this just makes sense.They can *still* get anything injected into them.You need to add your boostrapGuiceContextListener to your web.xmlFor Servlet < 3.0 you need to add a com.google.inject.servlet.GuiceFilter to /*
Guice 201Why does this rock? (Hint GWT stuff…) Can you say RemoteServiceServlet?No more calls to getThreadLocalX() for servlet context stuff. Just use Provider<T>
Guice 201: WarpThe Warp-* projects provide a lot of utility ops for Guice:@Transactional scopeTransaction per RequestSome stuff not dissimilar to Spring WebFlow or Stripes.
Guice 201: More Config@Named lets you provide named values in your configuration. (You can also create custom annotations)You can also use @Provides for factory methods in your modules for simple providers@Provides public Connection getConnection(@Named(“jdbc-url”) String jdbcUrl) {DriverManager.forName(whatever);DriverManager.getConnection(jdbcUrl);}
Guice 201: More Configbinder.bind(String.class).annotatedWith(Names.named(“jdbc-url”)).toInstance(“jdbc:mysql://localhost/mydb”);Note: @Provides methods could do JNDI lookups, or get other stuff. (This is a stupid example!)
Of Junipers and BathtubsGin is Google Guice for GWT client side apps.Based on DeferrredBinding.Certain features lost:Binding .toInstance() on any moduleAnonymous Provider<T> can’t be done (@Provides is *kinda* OK)Scoping needs to be by hard class reference.
Of Junipers and BathtubsThat is.. in(Singleton.class) not .asEagerSingleton() or with @SingletonGin seems both stupid and too smart.Binding a RemoteServiceAsync class works out of the box…Unless you want to do @ProvidesGin created classes are new Class() not GWT.create(Class.class); -- except for RemoteServiceAsync, which is a special scope.
Gin 101@GinModules(MyGinModule.class)public interface Injector extends Ginjector {    public static final Injector INSTANCE = GWT.create(Injector.class);    public MyStartupClassstartupClass();}public classMyGinModuleextends AbstractGinModule {    @Override    protected void configure() {this.bind(Resources.class)            .toProvider(ResourcesProvider.class)            .in(Singleton.class)    }}public static class ResourcesProvider implements Provider<Resources> {     @Override     public Resources get() {            return GWT.create(Resources.class);     }}
Gin 101Does this step on the toes of DeBi? OK, maybe a little bit. Sure you could do a singleton Resources.INSTANCE but injection makes Unit testing without dropping into GWTTestCase more frequent. (Read: much, much faster)This reserves DeBi for what it is best for: local environment specific code.
Gin 201What can’t you do with Gin?Remember your Injector.INSTANCE is compile-time:No “toInstance()” bindings… ever.No “toProvider(AnonymousProvider(){})” providers need to be public scoped static classes at the least.Gin treats RemoteServiceAsync specially. You can do a provider, but if you try @Provides methods in your GinModule classes, you will get a duplicate declaration error.
Gin 201All this aside, stacked with DeBi, Gin can rock rough and stuff with its Afro Puffs.Replace your Startup call with a Sync method.Replace your Async classes with thing that talk to local storage.Automagically retry onFailure() methods on network errors while your uses if offline.
Way way moreWarp-* is some great stuff:http://code.google.com/p/warp-persist/http://code.google.com/p/google-sitebricks/Guice with JAX-WShttps://jax-ws-commons.dev.java.net/guice/(Strangely harder than JAX-RS)

Guice gin

  • 1.
    Sapphire Gimlets* RobertCooperReachCall.com*no onions
  • 2.
    GuiceDependency InjectionJava SourceconfigurationConvention over configurationFast
  • 3.
    GinGuice for GWTapps100% Client SideBased on Deferred Binding, so some limitationsFast
  • 4.
    Guicevs SpringSpring ConfigHellPromise of simplicityEver expanding config filesLots of subprojectsBecomes more brittle, in that it becomes harder to extract code for reuse.
  • 5.
    Guicevs SpringGuiceJava Source“configuration”Convention over configuration.Annotation basedOpposite of Spring in defaultsPrefer constructor injectionPrefer new instances (“Prototype”) over SingletonsProvider<T> interface encourages mixing scopesType Safe – you got static typing, use it!
  • 6.
  • 7.
    Guice 101public classMyClass { private final MyService service; @Injectpublic MyClass(finalMyService service){this.service = service;} public String sayHelloToUser(){ return this.service.hello();}} @ImplementedBy(MyServiceImpl.class)public interface MyService { public String hello();}
  • 8.
    Guice 101@Singletonpublic classMyServiceImpl implements MyService { private final Provider<MySessionObject> sessionProvider; public MyServiceImpl(final Provider<MySessionObject> sessionProvider){this.sessionProvider = sessionProvider; } @Override public String hello() { return "Hello, "+sessionProvider.get().getName() +"!"; }}
  • 9.
    Guice 101import com.google.inject.servlet.SessionScoped;@SessionScopedpublicclass MySessionObject { private String name; public String getName(){ return this.name; } public void setName(String name){this.name = name; }}
  • 10.
    Guice 101What havewe done?MyClass gets a MyService injected.MyService is implemented by MyServiceImpl as a SingletonMyServiceImpl gets a Provider<MySessionObject>The hello() method fetches the Session scoped MySession object, and says Hello!
  • 11.
    Guice 101@ImplementedBy providesdefaults for any interface (You don’t need to config these if the default is OK)Injection is type safe on constructors (Unit tests have obvious requirements)Scope annotations (@SessionScoped, @Singleton) provide defaults.Provider<T> hides the scope shift from the Singleton service in a single thread method.
  • 12.
    Guice 101Making itwork on the web…
  • 13.
    Guice 101public classGuiceContextListener extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector( new Module() { public void configure(Binder binder) { // Oh Wait, we don’t need anything here! } } }, new ServletModule() { @Override protected void configureServlets() {this.serve(“/myPath/*”).with(MyServlet.class); } } }}
  • 14.
    Guice 101Warning! Overlycomplicated coming up!
  • 15.
    Guice 101@Singletonpublic classMyServlet extends HttpServlet{ private final Provider<MySessionObject> sessionProvider; private final MyClassmyClass; @Inject public MyServlet(final Provider<MySessionObject> sessionProvider, MyClassmyClass){this.sessionProvider = sessionProvider;this.myClass = myClass; } @Override public void doGet(HttpServletRequestreq, HttpServletResponse res) throws IOException {this.sessionProvider.get().setName(req.getParameter("name"));res.getWriter().println(myClass.hello()); }}
  • 16.
    Guice 101So thisis interesting. What happened there?The SessionScoped object was created, and set on the session.MyClass was created one off for injection into the servlet. Since it wasn’t a Provider<MyClass> it was implicitly @Singleton with the servletBut since the MyClass implementation used a provider, it ended up performing a singleton-session scoped op.
  • 17.
    Guice 101What else?Servlets,Filters, etc must always be @Singleton of course, this just makes sense.They can *still* get anything injected into them.You need to add your boostrapGuiceContextListener to your web.xmlFor Servlet < 3.0 you need to add a com.google.inject.servlet.GuiceFilter to /*
  • 18.
    Guice 201Why doesthis rock? (Hint GWT stuff…) Can you say RemoteServiceServlet?No more calls to getThreadLocalX() for servlet context stuff. Just use Provider<T>
  • 19.
    Guice 201: WarpTheWarp-* projects provide a lot of utility ops for Guice:@Transactional scopeTransaction per RequestSome stuff not dissimilar to Spring WebFlow or Stripes.
  • 20.
    Guice 201: MoreConfig@Named lets you provide named values in your configuration. (You can also create custom annotations)You can also use @Provides for factory methods in your modules for simple providers@Provides public Connection getConnection(@Named(“jdbc-url”) String jdbcUrl) {DriverManager.forName(whatever);DriverManager.getConnection(jdbcUrl);}
  • 21.
    Guice 201: MoreConfigbinder.bind(String.class).annotatedWith(Names.named(“jdbc-url”)).toInstance(“jdbc:mysql://localhost/mydb”);Note: @Provides methods could do JNDI lookups, or get other stuff. (This is a stupid example!)
  • 22.
    Of Junipers andBathtubsGin is Google Guice for GWT client side apps.Based on DeferrredBinding.Certain features lost:Binding .toInstance() on any moduleAnonymous Provider<T> can’t be done (@Provides is *kinda* OK)Scoping needs to be by hard class reference.
  • 23.
    Of Junipers andBathtubsThat is.. in(Singleton.class) not .asEagerSingleton() or with @SingletonGin seems both stupid and too smart.Binding a RemoteServiceAsync class works out of the box…Unless you want to do @ProvidesGin created classes are new Class() not GWT.create(Class.class); -- except for RemoteServiceAsync, which is a special scope.
  • 24.
    Gin 101@GinModules(MyGinModule.class)public interfaceInjector extends Ginjector { public static final Injector INSTANCE = GWT.create(Injector.class); public MyStartupClassstartupClass();}public classMyGinModuleextends AbstractGinModule { @Override protected void configure() {this.bind(Resources.class) .toProvider(ResourcesProvider.class) .in(Singleton.class) }}public static class ResourcesProvider implements Provider<Resources> { @Override public Resources get() { return GWT.create(Resources.class); }}
  • 25.
    Gin 101Does thisstep on the toes of DeBi? OK, maybe a little bit. Sure you could do a singleton Resources.INSTANCE but injection makes Unit testing without dropping into GWTTestCase more frequent. (Read: much, much faster)This reserves DeBi for what it is best for: local environment specific code.
  • 26.
    Gin 201What can’tyou do with Gin?Remember your Injector.INSTANCE is compile-time:No “toInstance()” bindings… ever.No “toProvider(AnonymousProvider(){})” providers need to be public scoped static classes at the least.Gin treats RemoteServiceAsync specially. You can do a provider, but if you try @Provides methods in your GinModule classes, you will get a duplicate declaration error.
  • 27.
    Gin 201All thisaside, stacked with DeBi, Gin can rock rough and stuff with its Afro Puffs.Replace your Startup call with a Sync method.Replace your Async classes with thing that talk to local storage.Automagically retry onFailure() methods on network errors while your uses if offline.
  • 28.
    Way way moreWarp-*is some great stuff:http://code.google.com/p/warp-persist/http://code.google.com/p/google-sitebricks/Guice with JAX-WShttps://jax-ws-commons.dev.java.net/guice/(Strangely harder than JAX-RS)