You are previewing Dependency Injection: Design patterns using Spring and Guice.
O'Reilly logo
Dependency Injection: Design patterns using Spring and Guice

Book Description

In object-oriented programming, a central program normally controls other objects in a module, library, or framework. With dependency injection, this pattern is inverted—a reference to a service is placed directly into the object which eases testing and modularity. Spring or Google Guice use dependency injection so you can focus on your core application and let the framework handle infrastructural concerns.

Dependency Injection explores the DI idiom in fine detail, with numerous practical examples that show you the payoffs. You'll apply key techniques in Spring and Guice and learn important pitfalls, corner-cases, and design patterns. Readers need a working knowledge of Java but no prior experience with DI is assumed.

Table of Contents

  1. Praise from the Creator of Guice
  2. Copyright
  3. Preface
  4. Acknowledgments
  5. About This Book
  6. About the cover illustration
  7. 1. Dependency injection: what's all the hype?
    1. 1.1. Every solution needs a problem
      1. 1.1.1. Seeing objects as services
    2. 1.2. Pre-DI solutions
      1. 1.2.1. Construction by hand
      2. 1.2.2. The Factory pattern
      3. 1.2.3. The Service Locator pattern
    3. 1.3. Embracing dependency injection
      1. 1.3.1. The Hollywood Principle
      2. 1.3.2. Inversion of Control vs. dependency injection
    4. 1.4. Dependency injection in the real world
      1. 1.4.1. Java
      2. 1.4.2. DI in other languages and libraries
    5. 1.5. Summary
  8. 2. Time for injection
    1. 2.1. Bootstrapping the injector
    2. 2.2. Constructing objects with dependency injection
    3. 2.3. Metadata and injector configuration
      1. 2.3.1. XML injection in Spring
      2. 2.3.2. From XML to in-code configuration
      3. 2.3.3. Injection in PicoContainer
      4. 2.3.4. Revisiting Spring and autowiring
    4. 2.4. Identifying dependencies for injection
      1. 2.4.1. Identifying by string keys
      2. 2.4.2. Limitations of string keys
      3. 2.4.3. Identifying by type
      4. 2.4.4. Limitations of identifying by type
      5. 2.4.5. Combinatorial keys: a comprehensive solution
    5. 2.5. Separating infrastructure and application logic
    6. 2.6. Summary
  9. 3. Investigating DI
    1. 3.1. Injection idioms
      1. 3.1.1. Constructor injection
      2. 3.1.2. Setter injection
      3. 3.1.3. Interface injection
      4. 3.1.4. Method decoration (or AOP injection)
    2. 3.2. Choosing an injection idiom
      1. 3.2.1. Constructor vs. setter injection
      2. 3.2.2. The constructor pyramid problem
      3. 3.2.3. The circular reference problem
      4. 3.2.4. The in-construction problem
      5. 3.2.5. Constructor injection and object validity
    3. 3.3. Not all at once: partial injection
      1. 3.3.1. The reinjection problem
      2. 3.3.2. Reinjection with the Provider pattern
      3. 3.3.3. The contextual injection problem
      4. 3.3.4. Contextual injection with the Assisted Injection pattern
      5. 3.3.5. Flexible partial injection with the Builder pattern
    4. 3.4. Injecting objects in sealed code
      1. 3.4.1. Injecting with externalized metadata
      2. 3.4.2. Using the Adapter pattern
    5. 3.5. Summary
  10. 4. Building modular applications
    1. 4.1. Understanding the role of an object
    2. 4.2. Separation of concerns (my pants are too tight!)
      1. 4.2.1. Perils of tight coupling
      2. 4.2.2. Refactoring impacts of tight coupling
      3. 4.2.3. Programming to contract
      4. 4.2.4. Loose coupling with dependency injection
    3. 4.3. Testing components
      1. 4.3.1. Out-of-container (unit) testing
      2. 4.3.2. I really need my dependencies!
      3. 4.3.3. More on mocking dependencies
      4. 4.3.4. Integration testing
    4. 4.4. Different deployment profiles
      1. 4.4.1. Rebinding dependencies
      2. 4.4.2. Mutability with the Adapter pattern
    5. 4.5. Summary
  11. 5. Scope: a fresh breath of state
    1. 5.1. What is scope?
    2. 5.2. The no scope (or default scope)
    3. 5.3. The singleton scope
      1. 5.3.1. Singletons in practice
      2. 5.3.2. The singleton anti-pattern
    4. 5.4. Domain-specific scopes: the web
      1. 5.4.1. HTTP request scope
      2. 5.4.2. HTTP session scope
    5. 5.5. Summary
  12. 6. More use cases in scoping
    1. 6.1. Defining a custom scope
      1. 6.1.1. A quick primer on transactions
      2. 6.1.2. Creating a custom transaction scope
      3. 6.1.3. A custom scope in Guice
      4. 6.1.4. A custom scope in Spring
    2. 6.2. Pitfalls and corner cases in scoping
      1. 6.2.1. Singletons must be thread-safe
      2. 6.2.2. Perils of scope-widening injection
    3. 6.3. Leveraging the power of scopes
      1. 6.3.1. Cache scope
      2. 6.3.2. Grid scope
      3. 6.3.3. Transparent grid computing with DI
    4. 6.4. Summary
  13. 7. From birth to death: object lifecycle
    1. 7.1. Significant events in the life of objects
      1. 7.1.1. Object creation
      2. 7.1.2. Object destruction (or finalization)
    2. 7.2. One size doesn't fit all (domain-specific lifecycle)
      1. 7.2.1. Contrasting lifecycle scenarios: servlets vs. database connections
      2. 7.2.2. The Destructor anti-pattern
      3. 7.2.3. Using Java's Closeable interface
    3. 7.3. A real-world lifecycle scenario: stateful EJBs
    4. 7.4. Lifecycle and lazy instantiation
    5. 7.5. Customizing lifecycle with postprocessing
    6. 7.6. Customizing lifecycle with multicasting
    7. 7.7. Summary
  14. 8. Managing an object's behavior
    1. 8.1. Intercepting methods and AOP
      1. 8.1.1. A tracing interceptor with Guice
      2. 8.1.2. A tracing interceptor with Spring
      3. 8.1.3. How proxying works
      4. 8.1.4. Too much advice can be dangerous!
    2. 8.2. Enterprise use cases for interception
      1. 8.2.1. Transactional methods with warp-persist
      2. 8.2.2. Securing methods with Spring Security
    3. 8.3. Pitfalls and assumptions about interception and proxying
      1. 8.3.1. Sameness tests are unreliable
      2. 8.3.2. Static methods cannot be intercepted
      3. 8.3.3. Neither can private methods
      4. 8.3.4. And certainly not final methods!
      5. 8.3.5. Fields are off limits
      6. 8.3.6. Unit tests and interception
    4. 8.4. Summary
  15. 9. Best practices in code design
    1. 9.1. Objects and visibility
      1. 9.1.1. Safe publication
      2. 9.1.2. Safe wiring
    2. 9.2. Objects and design
      1. 9.2.1. On data and services
      2. 9.2.2. On better encapsulation
    3. 9.3. Objects and concurrency
      1. 9.3.1. More on mutability
      2. 9.3.2. Synchronization vs. concurrency
    4. 9.4. Summary
  16. 10. Integrating with third-party frameworks
    1. 10.1. Fragmentation of DI solutions
    2. 10.2. Lessons for framework designers
      1. 10.2.1. Rigid configuration anti-patterns
      2. 10.2.2. Black box anti-patterns
    3. 10.3. Programmatic configuration to the rescue
      1. 10.3.1. Case study: JSR-303
    4. 10.4. Summary
  17. 11. Dependency injection in action!
    1. 11.1. Crosstalk: a Twitter clone!
      1. 11.1.1. Crosstalk's requirements
    2. 11.2. Setting up the application
    3. 11.3. Configuring Google Sitebricks
    4. 11.4. Crosstalk's modularity and service coupling
    5. 11.5. The presentation layer
      1. 11.5.1. The HomePage template
      2. 11.5.2. The Tweet domain object
      3. 11.5.3. Users and sessions
      4. 11.5.4. Logging in and out
    6. 11.6. The persistence layer
      1. 11.6.1. Configuring the persistence layer
    7. 11.7. The security layer
    8. 11.8. Tying up to the web lifecycle
    9. 11.9. Finally: up and running!
    10. 11.10. Summary
  18. A. The Butterfly Container
    1. A.1. A DSL for dependency injection
    2. A.2. Application configuration
      1. A.2.1. The DSL basics
      2. A.2.2. The Factory chain
      3. A.2.3. Contextual injection via input parameters
      4. A.2.4. Reinjection via factory injection
  19. B. SmartyPants for Adobe Flex
    1. B.1. The class+name key
      1. B.1.1. Injection annotations
    2. B.2. Injector rules
      1. B.2.1. But how do I kickstart the whole thing?