PicoContainer

# About

- What is PicoContainer?
- Introduction
- Javadoc
- Downloads
- News
- FAQ
- Project Goals
- Support

# Core Concepts

- Component Lifecycle
- Dependency Injection
- Scoped Containers

# Dependency Injection

- Constructor Injection
- Setter Injection
- Annotated Field Injection
- Annotated Method Injection
- Typed Field Injection
- Named Field Injection
- Method Injection
- Multiple Injection
- Composite Injection
- Factory Injection
- Reinjection
- Injection via Providers

# Configuration

- Disambiguation

# Modifying Component Behaviors

- Modifying Behaviors
- Caching and Singletons
- Hiding Implementations
- Thread Safety Behaviors
- AOP Style Interception

# Advanced Concepts

- Fluent Style
- Arrays, Collections and Maps
- Leveraging Parameter Names
- Building Containers
- Component Properties
- Component Configuration
- Monitoring Component Events

# PicoContainer's Architecture

- Design Patterns
- Inversion of Control
- Component Adapters
- Mock Objects
- Terminology
- Container Comparisons
- Transparency

# Container Choices

- DefaultPicoContainer
- CommandLinePicoContainer
- PropertiesPicoContainer
- SystemPropertiesPicoContainer
- TransientPicoContainer
- TieringPicoContainer

# Dependant & Related

- Web Frameworks
- Scripting Support
- Persistence
- Logging

# Anti-patterns

- Propagating Dependency
- Long Constructor Argument List
- Container Dependency
- Unit Tests Use Container
- Singleton

# Help Pages

- Ambiguous Injectable
- Unprocessed Properties

# History

- Inversion of Control History

# Project Info

- Project
- Team

# Hosted by

# Tools

## Modifying Behaviors

PicoContainer can add behaviors to components automatically during instantiation.

Behaviors are deleivered 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.

See below for details on Caching and Singletons, Implementation Hiding and Hot Swapping, as well as Other behaviors

### General use

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.

## Thread Safety

When components are created by two threads concurrently, with the intention of the instance being cached, it is possible in a small percentage of cases for the first instance into the cache to be replaced with a second instance. To prevent this, you may want to try one of two behaviors to make the operation thread safe.

### Synchronizing

Synchronizing wraps object creation in Java's classic synchronize feature:

    pico = new DefaultPicoContainer(new Synchronizing().wrap(new Caching()));
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    pico = new DefaultPicoContainer();
    pico.as(SYNCHRONIZE, CACHE).addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    pico = new PicoBuilder().withSynchronizing().withCaching().build();
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    import static org.picocontainer.behaviors.Behaviors.synchronizing;
    import static org.picocontainer.behaviors.Behaviors.caching;
    ...
    pico = new PicoBuilder().withBehaviors(synchronizing(), caching()).build();
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

### Locking

Locking wraps object creation in JDK 1.5's ReentrantLock facility. It is suggested that this is a more efficient alternative to the Synchronizing behaviour above:

    pico = new DefaultPicoContainer(new Locking().wrap(new Caching()));
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    pico = new DefaultPicoContainer();
    pico.as(LOCK, CACHE).addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    pico = new PicoBuilder().withLocking().withCaching().build();
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

    import static org.picocontainer.behaviors.Behaviors.locking;
    import static org.picocontainer.behaviors.Behaviors.caching;
    ...
    pico = new PicoBuilder().withBehaviors(synchronizing(), caching()).build();
    pico.addComponent(Apple.class);
    Apple a1 = pico.getComponent(Apple.class);
    Apple a2 = pico.getComponent(Apple.class);
    // both the same instance

## Others

### Property Applying

This is where there are a number of setters for a component that will be could be set after instantiation. A way of handing in some configuration if you like.

    class Foo {
     String message;
     public void setMessage(String message) {
     this.message = message;
     }
     public String toString() {
     return message;
     }
    }
    ...
    pico = new DefaultPicoContainer(new PropertyApplying());
    pico.addComponent(Foo.class);
    PropertyApplicator pa = (PropertyApplicator) pico.getComponentAdapter(Foo.class);
    pa.setProperty("message", "hello");
    System.out.println(pico.getComponent(Foo.class)); // prints hello

    pico = new DefaultPicoContainer();
    pico.as(APPLY_PROPERTIES).addComponent(Foo.class);
    PropertyApplicator pa = (PropertyApplicator) pico.getComponentAdapter(Foo.class);
    pa.setProperty("message", "hello");
    System.out.println(pico.getComponent(Foo.class)); // prints hello

    pico = new PicoBuilder().withProperties().build();
    pico.addComponent(Foo.class);
    PropertyApplicator pa = (PropertyApplicator) pico.getComponentAdapter(Foo.class);
    pa.setProperty("message", "hello");
    System.out.println(pico.getComponent(Foo.class)); // prints hello

    import static org.picocontainer.behaviors.Behaviors.propertyApplying;
    ...
    pico = new PicoBuilder().withBehaviors(propertyApplying()).build();
    pico.addComponent(Foo.class);
    PropertyApplicator pa = (PropertyApplicator) pico.getComponentAdapter(Foo.class);
    pa.setProperty("message", "hello");
    System.out.println(pico.getComponent(Foo.class)); // prints hello

Handling Behavior Chains

    import static org.picocontainer.behaviors.Behaviors.caching;
    import static org.picocontainer.behaviors.Behaviors.propertyApplying;
    ...
    pico = new PicoBuilder().withBehaviors(caching(), propertyApplying()).build();
    pico.addComponent(Foo.class);
    Cached cached = (Cached) pico.getComponentAdapter(Foo.class);
    PropertyApplicator pa = (PropertyApplicator) getDelegate(PropertyApplicator.class);
    pa.setProperty("message", "hello");
    System.out.println(pico.getComponent(Foo.class)); // prints hello

### Automatic

This is where a component is going to be instantiated regardless of whether:

- it is looked up
- any component that needs it is looked up
- it is Startable

It is most likely that you're doing this because the component in question is self contained and doing something once only. Alternatively, you're cutting a legacy codebase over from nest-of-singletons to dependency injection in stages.

    class Foo {

     public Foo() {
     System.out.println("Foo was instantiated");
     }
    }

    ...
    pico = new DefaultPicoContainer(new Automatic());
    pico.addComponent(Foo.class);
    pico.addComponent("bar", String.class);
    pico.getComponent("bar"); // Foo instantiated too.

    pico = new DefaultPicoContainer();
    pico.as(AUTOMATIC).addComponent(Foo.class);
    pico.addComponent("bar", String.class);
    pico.getComponent("bar"); // Foo instantiated too.

    pico = new PicoBuilder().withAutomatic().build();
    pico.addComponent(Foo.class);
    pico.addComponent("bar", String.class);
    pico.getComponent("bar"); // Foo instantiated too.

    import static org.picocontainer.behaviors.Behaviors.automatic;
    ...
    pico = new PicoBuilder().withBehaviors(automatic()).build();
    pico.addComponent(Foo.class);
    pico.addComponent("bar", String.class);
    pico.getComponent("bar"); // Foo instantiated too.

### Handling Nested Chains of Behavior

###

### Where Next?

The Component Lifecycle page details the lifecycle concepts applicable to some components