• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Google Guice presentation at Montreal JUG - October 2010
 

Google Guice presentation at Montreal JUG - October 2010

on

  • 1,453 views

 

Statistics

Views

Total Views
1,453
Views on SlideShare
1,449
Embed Views
4

Actions

Likes
2
Downloads
62
Comments
0

1 Embed 4

http://www.linkedin.com 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Google Guice presentation at Montreal JUG - October 2010 Google Guice presentation at Montreal JUG - October 2010 Presentation Transcript

    • Dependency Injection with... Guice Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • About me  Mathieu Carbou  Expert Java Developer  + 6 years Open-Source projects  Code design, Web, Testing, Maven, Spring, WS, JMS, EDA, OSGI , Security, Hibernate, .... … and Google Guice !  http://code.mycila.com  http://blog.mycila.com  http://www.testatoo.org Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • About the next hour  Pre-DI anti-patterns  Evolutions in the Java World  DI advantages  A little word about Spring...  … and a long long time about Guice ! Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Manual instanciation public final class SignupService { public void signup(User user) { EmailService emailService = new EmailService(); emailService.setHost("smtp.company.com"); emailService.setPort(25); emailService.send( "killerapp@company.com", user.getEmail(), "Welcome to Killer App !"); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Factory pattern public final class SignupService { public void signup(User user) { EmailService emailService = EmailServiceFactory.getEmailService(); emailService.send( "killerapp@company.com", user.getEmail(), "Welcome to Killer App !"); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Service locator public void signup(User user) { // retreived from JNDI for example ServiceLocator serviceLocator = getServiceLocator(); EmailService emailService = serviceLocator.getEmailService("emailService"); emailService.send( "killerapp@company.com", user.getEmail(), "Welcome to Killer App !"); } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Bean factory public void signup(User user) { // retreived Spring's bean factory BeanFactory beanFactory = getBeanFactory(); EmailService emailService = EmailService) beanFactory.getBean("emailService"); emailService.send( "killerapp@company.com", user.getEmail(), "Welcome to Killer App !"); } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Design issues  Strong coupling (locator, factory, identifier)  No isolation  Difficult to test, refactor and maintain SignupService depends MailService depends depends ServiceLocator depends UserService UserRepository UserRepository Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Pre-DI Anti-Patterns  Potential issues  Static references never garbadged-collected  Static shared access issues (concurrency)  Static lazy initialization often badly coded  Bad responsibility for client and user classes Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Evolutions  Metadata representations  XML  Annotations  Misconception about annotations Annotations are metadata within classes introducing no dependencies at runtime. A class can be resolved even if its annotations are not in the classpath ! Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Evolutions  JSR250 (already in JDK6, commes from J2EE)  @Resource  @PostConstruct  @PreDestroy  JSR330 (next JDK, jar available)  @Inject  @Provider  @Named  @Singleton  @Scope Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Evolutions  Generics (type literals)  List<Employee> != List<User>  Some DI frameworks till rely on Class (Spring)  May crash at runtime (type erasure) !  New DI frameworks use TypeLiteral (Guice)  Errors caugth at compile time ! Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Evolutions  Example: public final class FireService { final List<Employee> employees; @Inject FireService(List<Employee> employees) { this.employees = employees; } public void fireAll() { for (Employee employee : employees) employee.fire(); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Evolutions  Guice: Compile error ! final class FireModule extends AbstractModule { protected void configure() { bind(new TypeLiteral<List<Employee>>(){}) .toInstance(Arrays.asList(new User())); } }  Spring (xml): compiles, but fails at runtime ! <bean name="fireService" class="com.mycompany.killerapp.FireService"> <constructor-arg> <list> <bean class="com.mycompany.killerapp.User"/> </list> </constructor-arg> </bean> Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • DI Definition  A dependant is contacted by its dependencies  Hollywood principle: Don't call me, I'll call you Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • DI Definition  Example: public final class FireService { final List<Employee> employees; @Inject FireService(List<Employee> employees) { this.employees = employees; } public void fireAll() { for (Employee employee : employees) employee.fire(); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • DI Advantages  Easier testing & refactoring  Easier maintenance  Loose coupling  Manage object lifetime  Better design and use (interfaces)  Hide implementation details  Write less code (and less bugs) Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • About Spring Framework  Everyone knows it  You can compare  Guice != Spring  Guice = Advanced DI framework  Spring = Integration Framework (JMX, JMS, JDBC, TX, Hibernate, ...) built upon a DI stack  You can use Spring classes with Guice Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice !  Open-Sourced by Google  First public release in 2007  http://code.google.com/p/google-guice/  Project's lead: Bob Lee  Cofounder of AOP Alliance  Creator of JAdvise and Dynaop  Strong AOP background Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice !  Version 3 to be released soon  Standardized DI annotations (JSR330)  Focus on:  Easy to use  Best DI capabilities  Not an integration framework Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Guice Servlets (DSL, DI and lifetime management for servlets and filters) <listener> <listener-class> com.company.web.guice.GuiceConfig </listener-class> </listener> <filter> <filter-name>Guice Filter</filter-name> <filter-class> com.google.inject.servlet.GuiceFilter </filter-class> </filter> <filter-mapping> <filter-name>Guice Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Guice Servlets (DSL, DI and lifetime management for servlets and filters) protected void configureServlets() { Map<String, String> params = new HashMap<String, String>(); /* Shirio Security */ bind(IniShiroFilter.class).in(Scopes.SINGLETON); filter("/*").through(IniShiroFilter.class); /* Wicket */ params.put(WicketFilter.FILTER_MAPPING_PARAM, "/*"); filter("/page/*").through(WicketGuiceFilter.class, params); bind(WebApplication.class).to(MyApplication.class); /* Jersey */ serve("/rest/*").with(GuiceContainer.class, params); } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Guice Persistence (Hibernate, JPA, DB4O, ...) protected void configurePersistence() { workAcross(UnitOfWork.TRANSACTION).usingJpa("c4sJpaUnit"); bind(DataSource.class) .toProvider(fromJndi(DataSource.class, "jdbc/c4sDS")) .in(Singleton.class); bind(PlayerRepository.class) .to(JpaPlayerRepository.class) .in(Singleton.class); bind(TeamRepository.class) .to(JpaTeamRepository.class) .in(Singleton.class); } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Guice Persistence (Dynamic finders) public interface TeamFinder { @Finder(query="from Team") List<Team> allTeams(); } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Guice Jndi class SqlModule extends AbstractModule { protected void configure() { bind(UserRepository.class).to(SQLUserRepository.class); bind(DataSource.class) .toProvider(fromJndi(DataSource.class, "jdbc/h2DB")) .in(Singleton.class); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Spring Integration  Assisted inject (contextual DI) interface PaymentFactory { Payment create(Date startDate, Money amount); } // DI configuration bind(Payment.class).to(PaymentImpl.class); bind(PaymentFactory.class) .toProvider(newFactory(PaymentFactory.class, RealPayment.class)); // user code Payement pay = factory.create(today, amount); Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Ecosystem  Projects extending Guice capabilities:  Peaberry (OSGI)  Mycila-testing  Guiceyfruit (JSR250, JNDI, ...)  Mycila-guice (JSR250, scopes, module discovery, …)  GuiceBerry  [...] Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Integration Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Guice relative Books Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Advantages  Easier to use, test, maintain, refactor, learn  Better power to complexity ratio than Spring  Advanced DI concepts  Favor good design  Immutability, valid objects  Thread-safe object  No more java beans constraints  Injectable DSL is possible Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Google Guice Advantages  No string identifier  No more conflicts  No more responsability issue  No more XML !  Static and compile-time verification  Plus many things we'll see in details now ! Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  DI configuration (Java-based, DSL & Fluent API) public final class SqlModule extends AbstractModule { @Override protected void configure() { bind(UserRepository.class).to(SQLUserRepository.class); bind(DataSource.class) .toProvider(fromJndi(DataSource.class,"jdbc/myDB")) .in(Singleton.class); } @Provides Connection connection(DataSource dataSource) throws SQLException { return dataSource.getConnection(); } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Dependency identification: Key class  Supports type literals and raw types  Bindings annotations  Static type checking  Errors caught at compile time, not at runtime Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Dependency identification bind(Properties.class) .annotatedWith(named("app-settings")) .toProvider(fromJndi(Properties.class, "settings/app")); bind(new TypeLiteral<GenericRepository<Employee>>(){}) .to(EmployeeRepository.class); -------------------------------------------------------------- Key key = Key.get(new TypeLiteral<GenericRepository<Employee>>(){}); GenericRepository<Employee> repo = injector.getInstance(key) Properties props = injector.getInstance( Key.get(Properties, named("app-settings"))) Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Bootstrapping Injector injector = Guice.createInjector( Stage.PRODUCTION, new MyModule(), new JSR250Module(), new SqlModule()); Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Injection points: Constructors, Fields, Methods public class BasicTemplateService { @Inject UserRepository repository private final Settings settings; @Inject public BasicTemplateService(Settings settings) { this.settings = settings; } @Inject @Named("/app/messages/user") void withMessageBundle(ResourceBundle rb) { [...] } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  AOP support  Easy  All casual cases  Intercept:  Methods  Injections  Matchers  Classes  Methods Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  AOP support - Interceptors bindInterceptor( Matchers.inPackage(getPackage("com.company.repository")), Matchers.annotatedWith(Test.class), new MyAopAllianceInterceptor()); package com.company.repository; class MyRepository { @Test void intercepted() {} } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  AOP support – Injection listeners bindListener(Matchers.any(), new TypeListener() { public <I> void hear(final TypeLiteral<I> type, final TypeEncounter<I> encounter) { System.out.println("Meeting type: " + type); encounter.register(new InjectionListener<I>() { public void afterInjection(I injectee) { System.out.println("Type has been injected"); } }); } }); Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Providers  Scope widening  Delay construction class CurrentLocale { @Inject Provider<HttpServletRequest> request; public Locale get() { [...] } } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Scopes  Object lifetime management  By default: no scope  Allows objects to be garbadged-collected shortly  Misconception about singletons  @Singleton IS a scope !  Should only considered when really needed  Constructing new objects has no cost in Java Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  Scopes bind(JamesBondMessage.class) .in(new ExpiringSingleton(10, SECONDS)); bindScope(Concurrent.class, new ConcurrentSingleton()); bind(EnglishDataLoader.class).in(Concurrent.class); bind(FrenchDataLoader.class).in(Concurrent.class); @Concurrent class SpanishDataLoader { } Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Dive into Guice  And also  Module overriding  Modules.override(...).by()...  Introspection API  Elements.getElements()  binding.acceptVisitor()  […]  Parent / Child injectors  Private / Public bindings Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com
    • Guice questions ? Copyright © 2010 – Mathieu Carbou – Mycila.com - mathieu.carbou@gmail.com