PicoContainer can add behaviors to components automatically during instantiation.
Behaviors are delivered by passing a BehaviorFactory reference into the PicoContainer instance on construction. For the most part BehaviorFactories are completely stateless, and the Behavior instances they make are not.
DefaultPicoContainer can take a behavior factory instance in its constructor:
pico = new DefaultPicoContainer(new BehaviorClass()); pico.addComponent(Foo.class); // other components added Foo foo = pico.getcomponent(Foo.class) // Foo instance will be affected by an additonal behavior.
Or it can take behaviours that wrap each other:
pico = new DefaultPicoContainer(new BehaviorClass().wrap(new AnotherBehaviorClass())); pico.addComponent(Foo.class); // other components added Foo foo = pico.getcomponent(Foo.class) // Foo instance will be affected by two additonal behaviors.
Behaviors can be signalled by properties per component:
pico = new DefaultPicoContainer(); pico.as(SOME_BEHAVIOR).addComponent(Foo.class); // the behavior has a property marking it, and the default component facory understands that property // other components added Foo foo = pico.getcomponent(Foo.class) // Foo instance will be affected by an additonal behavior.
You can build a container with the applicable property:
pico = new PicoBuilder().withXXXBehavior().build(); pico.addComponent(Foo.class); // other components added Foo foo = pico.getcomponent(Foo.class) // Foo instance will be affected by an additonal behavior.
Behaviors can be chained together by PicoBuilder:
import static org.picocontainer.behaviors.Behaviors.xxxxxxx; import static org.picocontainer.behaviors.Behaviors.yyyyyyy; ... pico = new PicoBuilder().withBehaviors(xxxxxxx(), yyyyyyy()).build(); pico.addComponent(Foo.class); // other components added Foo foo = pico.getcomponent(Foo.class) // Foo instance will be affected by two additonal behaviors.
Caching is where PicoContainer ensures that the same component instance is returned for second and subsequent getComponent() invocations. See the Caching behavior page. Other Dependency Injection Containers call this Singleton behavior.
Hiding Implementations is where PicoContainer ensures that the component that implements a abstract type can only be used as that abstract type by components that depend on it. Casting back to the implementation is vetoed. See the Hiding behavior page.
Synchronizing and Locking are variations on where PicoContainer ensures that components can used in a thread-safe way. See the Thread Safety behavior page.
AOP Style Interception is where PicoContainer can invoke functionality before or after component method execution. See the Interception behavior page.