PicoContainer is an IoC (inversion of control) container that will automatically handle relationships between components for you. You can read more about the problems it solves and issues it addresses at http://www.picocontainer.org/
. Basically it removes the need for you to worry about lookups and passing in components into your actions. If all this sounds a little abstract, here is a trivial example.
Let us say that you have a number of actions that require a UserManager component. These actions have no relationship to one another and no commonality beyond that requirement. So, one potential solution would be to introduce a base class that handles looking up and instatiating your UserManager. This however violates a number of sensible design principles, and needlessly cripples your actions. What happens if a few weeks down the line you need a TransactionManager, then later on a Scheduler? Your base class will mushroom out of control, and your actions will all suddenly get a Scheduler component regardless of whether they have any interest in such a component.
Enter picocontainer, which will elegantly solve this problem for you. The rest of this article will take you through the process of integrating picocontainer in your webwork application step by step.
For the purposes of this example, we will assume that you actions require a combination of a UserManager and a Scheduler.
Download all required picocontainer jars.
These are:
picocontainer.jar
picoextras-integration.jar
picoextras-servlet.jar
picoextras-webwork.jar
These can all be found at http://dist.codehaus.org/picocontainer/jars/
. The latest versions of each will do.
Download these 4 jar files into your WEB-INF/lib directory.
Register the containers to listen to session and application scopes.
Add the following to your web.xml:
<listener>
<listener-class>org.picoextras.servlet.ServletContainerListener</listener-class>
</listener>
Register the pico-webwork dispatcher.
This dispatcher behaves identically to the webwork dispatcher, but performs the extra step of building a container for each request and ensuring webwork actions are created appropriately.
Modify the mapping for your action servlet in web.xml to the following:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.picoextras.webwork.PicoServletDispatcher</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Implement your container assembler class.
This class is responsible for assembling all the components required for your container. In our case, we have two components: UserManager and Scheduler. Our container assembler will therefore look something like this:
package com.mydomain.webwork;
public class WebContainerAssembler
implements org.picoextras.integrationkit.ContainerAssembler
{
public void assembleContainer(MutablePicoContainer container, String name)
{
if (name.equals("application"))
{
container.register(Scheduler.class, new Scheduler());
}
else if (name.equals("session"))
{
}
else if (name.equals("request"))
{
container.register(UserManager.class, new LDAPUserManager());
}
}
}
In this particular case we have our class hardcoded for the sake of simplicity, but you're free to use whatever mechanism you want.
Note that the container names (application, session, request) are flexible, so you could for example add different containers based on your needs. For example, you could have an "action" container name that will create a new instance of your component for every action.
Register your ContainerAssembler.
In your web.xml file, add the following:
<context-param>
<param-name>assembler</param-name>
<param-value>com.mydomain.webwork.WebContainerAssembler</param-value>
</context-param>
In addition to this, you will need to inform webwork that it should use the picocontainer aware action factory to construct actions. Add the following line to your webwork.properties file:
webwork.action.factory=org.picoextras.webwork.WebWorkActionFactory
Modify your Actions.
Now that the picocontainer setup is complete, the final step is to modify your actions so as to use the components that are now available. All you have to do is ensure you have a suitable constructor that takes in as a parameter the components it is interested in. So for example:
public class MyAction extends ActionSupport
{
public MyAction(UserManager manager, Scheduler scheduler)
{
}
}
...and that's it! picocontainer will take care of all the plumbing, and will automatically wire up your actions with your components, leaving you free to deal with business logic and presentation fun!
Note, that as of 17 Jan 05 - you can create objects outside of webwork by using the property
You just need to implement a simple interface: