Apache Struts 2 Documentation > Xwork's Component Architecture |

Apache Struts 2 Documentation
Xwork's Component Architecture
Edit Page Browse Space Add Page Add News
Added by gjz22, last edited by Ted Husted on Feb 04, 2007 (view change)

| These documents are out of date. As of WebWork 2.2, the WebWork IoC container has been deprecated (though not removed) and the WebWork team recommends you use Spring Plugin for all your IoC needs

## Writing Component Classes

In XWork the actual component class can be virtually anything you like. The only constraints on it are that it must be a concrete class with a default constructor so that XWork can create instances of it as required. Optionally, a component may implement the Initializable and/or Disposable interfaces so it will receive lifecycle events just after it is created or before it is destroyed. Simply:

    public class MyComponent implements Intializable, Disposable {
        public void init () {
             //do initialization here
        }

        public void dispose() {
             //do any clean up necessary before garbage collection of this component
        }
    }

## Component Dependencies

One feature that is not immediately obvious is that it is possible for components to depend on other components. For example if the ExchangeRateService described above depended on a Configuration component, XWork will pass the Configuration component through to the ExchangeRateService instance after ExchangeRateService is instantiated. Note that XWork automatically takes care of initializing the components in the correct order, so if A is an action or component that depends on B and C, and B depends on C and if A, B, and C have not been previously instantiated, the ComponentManager will in the following order:

1. Instantiate C and call it's init() method if it implements Initializable.
2. Instantiate B, then using the enabler method, set C to be used by B
3. Call B's init() method, if it implements Intitializable.
4. Set B using B's enabler method to be used by A.

And so on and so forth. Of course, if there are instances of B or C that would be reused in this case, those instances would be passed using the enabler method rather than a new instance.

## Writing Enablers

An enabler should consist of just a single method that accepts a single parameter. The parameter class should either be the component class that is to be enabled, or one of the component's superclasses. XWork does not care what the name of the enabler's method is.

Here is an example of what the ExchangeRateAware enabler might look like:

    public interface ExchangeRateAware {
        public void setExchangeRateService(ExchangeRateService exchangeRateService);
    }

Note that typically an enabler would be an interface, however there is nothing to prevent you from using a class instead if you so choose.

## Writing "Enabler-aware" Actions

All an action needs to do is implement the relevant enabler interface. XWork will then call the action's enabler method just prior to the action's execution. As a simple example:

    public class MyAction extends ActionSupport implements ExchangeRateAware {
        ExchangeRateService ers;

        public void setExchangeRateService(ExchangeRateService exchangeRateService) {
            ers = exchangeRateService;
        }

        public String execute() throws Exception {
            System.out.println("The base currency is " + ers.getBaseCurrency());
        }
    }

If you have an object that is not an action or another component, you must explictly tell XWork to supply any enabled components to your object by calling componentManager.initializeObject(enabledObject);

## Using an external reference resolver

You can also use an external reference resolver in XWork, i.e., references that will be resolved not by XWork itself. One such example is using an external resolver to integrate XWork with the Spring Framework

You just need to write an external reference resolver and then tell XWork to use it in the package declaration:

    <package
        name="default"
        externalReferenceResolver="com.atlassian.xwork.ext.SpringServletContextReferenceResolver">

Now, to use external references you do something like this:

    <external-ref name="foo">Foo</external-ref>

Where the name attribute is the setter method name and Foo is the reference to lookup.

For more details and sample code about this integration, take a look at the javadocs to the com.opensymphony.xwork.config.ExternalReferenceResolver class (unfortunately unavailable online) and at XW-122

-Chris