[ TODO ]

Pico 3 is being worked on a github: &

Features in use

Injection styles

  • Constructor injection
  • Annotated field injection (currently with @org.picocontainer.annotations.Inject, when PICO-380 is fixed, we can use @javax.inject.Inject)


  • we have a custom CompositeLifecycleStrategy to work around PICO-381
  • we support a StartableLifecycleStrategy, for components implementing info.magnolia.objectfactory.Startable and info.magnolia.objectfactory.Disposable
  • we support @javax.annotation.PostConstruct and @javax.annotation.PreDestroy
  • we support a custom @info.magnolia.objectfactory.AtStartup for components that need to be started "at startup" (how surprising), as opposed to lazily (i.e when they are requested)


For now, the only org.picocontainer.ComponentMonitor we use is a logging component, i.e logging what the container is doing (instantiating, etc)

  • try picocontainer 3 (an alpha should be released soon)


We currently have two containers:

  • root
  • main

The root container is meant to be used only at startup/shutdown (i.e in MagnoliaServletContextListener), and should only contain a minimal set of components, necessary to startup the system. Projects which would require customizing the startup procedure (for example using a different resolution mechanism for files) would override this default set of component by overriding MagnoliaServletContextListener.populateRootContainer(). I don't think it's worth investing into a more configurable setup for root components, at least until we have a good use-case. (Since one would have to implement such startup components, they might as well override MagnoliaServletContextListener while they're at it)

The main container is populated with all known components (currently from properties, in the future using components registered in module descriptors), module classes, and so on. This container is wrapped in PicoComponentProvider.

PicoComponentProvider.getComponent() simply provides instances of known components. PicoComponentProvider.newInstance() makes sure the request class is not a registered component (to avoid clashes - TBC), creates a temporary container as a child of the current container, registers the request component in it and requests it immediately.


Strings and other "simple" classes

When c2b instantiates components, it now goes through PicoComponentProvider.newInstance. When instantiating, for example, LocaleDefinition, we run into potential issues (if only of performance), because LocaleDefinition has a test-friendly constructor taking 3 Strings. Pico tries to satisfy the greediest constructor, and a such checks if there are candidate for this constructor. I've noticed that, in turn (perhaps this is a flaw in c2b or PicoCP) we're trying to satisfy the java.lang.String constructors. Just found this in the javadoc of org.picocontainer.MutablePicoContainer#addComponent:

  • <li><strong>Force No-Arg constructor usage:</strong> If you wish to force a component to be constructed with
  • the no-arg constructor, use a zero length Parameter array. Ex: <code>new Parameter0</code>

Scoped containers

Session and request scopes. Containers need to somehow be "swapped".
What/where will we register in these containers ? This is maybe where "composers" might be useful (registered in module descriptors).

  • User (scope=session)
  • (Web)Context (scope=req)
  • The request response and session objets themselves
  • ... ?

Components such as rendering models could then depend on such request or session-scoped components.

Named dependencies

This could be nice to avoid depending on configuration properties objects and do a look up there.
Instead one could depend on, say @Named("myProperty") String myProperty.
@Named might for this, but we might want to make it more explicit with, for example @PropertyConfiguration, which could be a @javax.inject.Qualifier.

A quick investigation led me to org.picocontainer.parameters.ConstantParameter, which is maybe where we'll need to hook up our custom property lookup

Features we could/should use

  • Classloader swapping. There's PicoContainer implementation which is able to "juggle" classloaders. To investigate, but could be very useful for the module (down)loader, for example. It also makes use of org.picocontainer.classname.ClassName, which as far as I can tell, could be useful for use, avoiding "Class<T> silentForName(String s)". Might require changing a method from private to protected if we want to keep on using our ClassFactory system, or going away from that (see groovy module)
  • JMX - see
  • No labels