Dashboard > WebWork 1 > WebWork CookBook > PicoContainer Integration
  WebWork 1 Log In View a printable version of the current page.  
  PicoContainer Integration
Added by Hani Suleiman, last edited by Hani Suleiman on Apr 25, 2004  (view change)
Labels: 
(None)

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")) 
    {
      //we create one scheduler and put it in our application scope
      container.register(Scheduler.class, new Scheduler());
    }
    else if (name.equals("session")) 
    {
      //we don't have any session specific components
    }
    else if (name.equals("request")) 
    {
      //we create a new UserManager for every 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)
  {
    //store refs, lookup stuff, whatever you want.
  }
}

...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

webwork.injection.objectcreator=webwork.util.injection.DefaultObjectCreator

You just need to implement a simple interface:

ObjectCreator.java
public interface ObjectCreator
{
    public Object instantiate(Class actionClass) throws IllegalAccessException, InstantiationException;

    public Object instantiateBean(ClassLoader classloader, String className) throws IOException, ClassNotFoundException;
}
Posted by Scott Farquhar at Jan 17, 2005 01:15 | Permalink
Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request - Contact Administrators