Sapphire Gimlets

  • 544 views
Uploaded on

Gin and Guince

Gin and Guince

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
544
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Sapphire Gimlets*
    Robert Cooper
    ReachCall.com
    *no onions
  • 2. Guice
    Dependency Injection
    Java Source configuration
    Convention over configuration
    Fast
  • 3. Gin
    Guice for GWT apps
    100% Client Side
    Based on Deferred Binding, so some limitations
    Fast
  • 4. Guicevs Spring
    Spring Config Hell
    Promise of simplicity
    Ever expanding config files
    Lots of subprojects
    Becomes more brittle, in that it becomes harder to extract code for reuse.
  • 5. Guicevs Spring
    Guice
    Java Source “configuration”
    Convention over configuration.
    Annotation based
    Opposite of Spring in defaults
    Prefer constructor injection
    Prefer new instances (“Prototype”) over Singletons
    Provider<T> interface encourages mixing scopes
    Type Safe – you got static typing, use it!
  • 6. Guice 101
    Basic Annotations
    @Inject
    @ImplementedBy/@ProvidedBy
    @[Scope]
    @Named
  • 7. Guice 101
    public 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();}
  • 8. Guice 101
    @Singleton
    public 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() +"!";
    }
    }
  • 9. Guice 101
    import com.google.inject.servlet.SessionScoped;
    @SessionScoped
    public class MySessionObject {
    private String name;
    public String getName(){
    return this.name;
    }
    public void setName(String name){
    this.name = name;
    }
    }
  • 10. Guice 101
    What have we done?
    MyClass gets a MyService injected.
    MyService is implemented by MyServiceImpl as a Singleton
    MyServiceImpl gets a Provider<MySessionObject>
    The hello() method fetches the Session scoped MySession object, and says Hello!
  • 11. 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.
  • 12. Guice 101
    Making it work on the web…
  • 13. Guice 101
    public 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);
    }
    }
    }
    }
  • 14. Guice 101
    Warning! Overly complicated coming up!
  • 15. Guice 101
    @Singleton
    public 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());
    }
    }
  • 16. Guice 101
    So 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 servlet
    But since the MyClass implementation used a provider, it ended up performing a singleton-session scoped op.
  • 17. Guice 101
    What 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.xml
    For Servlet < 3.0 you need to add a com.google.inject.servlet.GuiceFilter to /*
  • 18. Guice 201
    Why does this rock? (Hint GWT stuff…)
    Can you say RemoteServiceServlet?
    No more calls to getThreadLocalX() for servlet context stuff. Just use Provider<T>
  • 19. Guice 201: Warp
    The Warp-* projects provide a lot of utility ops for Guice:
    @Transactional scope
    Transaction per Request
    Some stuff not dissimilar to Spring WebFlow or Stripes.
  • 20. 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);
    }
  • 21. Guice 201: More Config
    binder.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 and Bathtubs
    Gin is Google Guice for GWT client side apps.
    Based on DeferrredBinding.
    Certain features lost:
    Binding .toInstance() on any module
    Anonymous Provider<T> can’t be done (@Provides is *kinda* OK)
    Scoping needs to be by hard class reference.
  • 23. Of Junipers and Bathtubs
    That is.. in(Singleton.class) not .asEagerSingleton() or with @Singleton
    Gin seems both stupid and too smart.
    Binding a RemoteServiceAsync class works out of the box…
    Unless you want to do @Provides
    Gin 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 interface Injector extends Ginjector {
    public static final Injector INSTANCE = GWT.create(Injector.class);
    public MyStartupClassstartupClass();
    }
    public class Module extends 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 101
    Does 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.
  • 26. Gin 201
    What 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.
  • 27. Gin 201
    All 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.
  • 28. Way way more
    Warp-* 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)