This document discusses moving from Plexus dependency injection to JSR 330 and Google Guice. It outlines reasons for the move, such as Plexus lacking documentation and type safety. It then covers how Guice provides a standard, flexible and type-safe approach. The document proposes a migration path and shim to support both Plexus and JSR 330 components. It also discusses customizing Guice through listeners and conventions. Finally, it suggests next steps like dynamic Guice applications and integrating with OSGi.
2. Why move?
● Plexus is not widely used outside of Maven
● Lack of documentation, not always up-to-date
● Extra steps needed to generate Plexus XML
● Not type-safe, lacks support for generics
3. ● Single plexus.xml
● META-INF/plexus/components.xml (Class-Path)
4. ● Has annotations, but still need to generate XML
5. Why ?
● Standard: reference implementation for JSR 330
● Flexible: can map all sorts of metadata to bindings
● Type-safe: detailed messages when things go wrong
● Modular: multiple extensions available, OSGi-ready
6. JSR 330
● New standard for Java dependency injection
// Constructor injection
// Field injection
// Setter injection
7. ● Fluent Java binding API
● Records generic information lost during erasure
● Can be driven by Java / annotations / XML / ...etc...
8. Migration Path
● Preserve investment in legacy Plexus components
● Allow gradual migration to JSR 330 annotations
● Must support mixture of Plexus and JSR 330
9. Customizing
● Guice provides an SPI to hook into injections
● TypeListeners called for matching bound types
● Register MembersListeners for custom injection
● Register InjectionListeners for custom lifecycles
● SPI supports binding introspection / rewriting
11. -y Beans
● Writing all those listener classes can get tedious
●
guice-bean library cuts out most of the work
● You provide a BeanBinder implementation
● that can provide PropertyBinders for each type
● which can supply PropertyBindings for each property
● Bean conventions select field / setter properties
13. Metadata
● Canonical form of Plexus bindings
● Captures @Component implementations
●
● Maps @Component bean properties to
● @Requirement settings
● @Configuration settings
● Interns Plexus hint strings to save space
14. Scanning for Metadata
● ClassSpace abstraction supplies classes / resources
● Can be backed by Plexus Classworlds or OSGi
● Plexus XML mapped into Plexus annotations
● Plexus annotations are interpolated and stored
15. Converting Configuration
● Builds on top of standard Guice TypeConverters
● Supports properties, nested collections, and beans
● Guice SPI lets you add your own TypeConverters
16. Locating Components
● Guice bindings map Keys to Providers
● Each Key has a type and optional annotation
● Plexus components have roles and hints
Key == Class<Role> + @Named(hint)
● Uses Guice SPI to find component bindings
17. Binding Components
● Opposite of locating components
● @Component roles and hints turned into Keys
● Keys used to bind component implementations
● Singleton default, unless strategy is "per-lookup"
18. Injecting Requirements
● @Requirement locate Plexus components
● Handles Maps, Lists, instances, and Wildcards
● Loggers automatically configured and injected
● @Configuration convert constant using type
19. Managing Lifecycles
● Uses an InjectionListener to listen for bean instances
● Plexus lifecycle "personality" applied after injection
● Reverse lifecycle applied when container disposed
● Need to manage extra metadata (like descriptions)
21. Classworlds
● Plexus Container API still depends on Classworlds
● But dependency is much less in guice-plexus-shim
● Just need to write classworlds-shim around OSGi
● ... to get Plexus apps running on OSGi containers
22. Extending JSR 330
● JSR 330 tells us how to mark dependencies
● and qualify them (just like with Plexus hints)
● But it does not say how to mark components
23. Identifying JSR 330 components
● Wrap the Class-Path up as a ClassSpace and scan it
● Look for classes with qualifiers such as @Named
● Empty @Named means "use class name" instead
● Binding type found by analysing class hierarchy
24. Next Steps
● We can now run Plexus apps on top of Guice
● ... and start separating apps into OSGi bundles
● OSGi lets us dynamically add / remove bundles
● ... but Guice bindings are static
25. Next Steps
● How can we resolve this mismatch?
● Find out in "Dynamic Guice Applications" ...