magpiebrain

Sam Newman's site, a Consultant at ThoughtWorks

When you configure your XWork application (be-it WebWork or something else), you define your Action, Interceptors which intercept Action invocation, and Results, which get executed when an Action returns. You have complete control over the implementation of these classes – beyond the fact that you need to implement some basic interfaces (@Action@, @Interceptor@ and @Result@ respectively), however you have absolutely no control over how these classes get instantiated by XWork at runtime – internally XWork just gets your class, and calls @newInstance@. The limit of control you have over how Xwork sets these objects up is in the form of String/Value pairs defined in the configuration.

So why is this a problem? Well, lets take the example of my “Swing/XWork prototype(A GUI framework using XWork)”:http://www.magpiebrain.com/archives/000181.html I posted earlier. In it I created an Interceptor to monitor the progress of an Action. As the Action is invoked and completed, my Interceptor calls methods on a @ProgressRegister@ object. The problem is that I cannot pass references to my @ProgressRegister@ object into the interceptor when created – I am forced into creating a Singleton method accessor on @ProgressRegister@. In an ideal world, I would be able to define my @ProgressRegister@ object, and tell XWork that this object instance should be passed in whenever my interceptor is created:



...







This is of course exactly how IoC frameworks like Spring and Pico container work (the @bean@ definition from above is actually lifted straight from a Spring XML file). Ideally, XWork’s configuration could be overhauled to use Spring internally, but this is a big job. Instead I have a compromise.

Lets imagine an Interceptor class called @SpringInteceptorFactory@ which implements @Interceptor@. It takes a single string parameter which equates to the name of another Interceptor defined in a Spring config file. When invoked by XWork, @SpringInteceptorFactory@ creates an Interceptor of the relevant type (with properly wired dependencies) and executes it accordingly. This same solution could be used to create @Result@ or @Action@ objects. I can’t escape the feeling that adding yet another config file (in the shape of a Spring XML definition) is going to complicate things, however if you were already going to use Spring (Or Pico/NanoContainer) perhaps its not that much hassle after all.

5 Responses to “XWork: Actions, Interceptors, Results and IoC”

  1. Jason Carreira

    You could also populate the ActionContext ThreadLocal with the relevant objects your Interceptors can use. Your calling object could be set up using Spring to have the objects it needs, then put them in the extra context map that you pass to the ActionProxyFactory, and they will be available to your Interceptor via ActionContext.getContext().get(KEY);

    I do want to make it easier to make these other objects be built by outside containers, but it’s going to have to wait till at least 1.1….

    Reply
  2. Juan Murillo

    This of course also begs the question of whether a command pattern implementation on top of Spring would be an interesting addition to that framework, considering it already has AOP for interceptors and lightweight container for contexts.

    Reply
  3. Sam Newman

    I think that is what XWork would become if you integrated it with Spring. Much of XWork’s internals would vanish to be replaced by Spring. I’m actually starting to think that in such a situation there is very little XWork left…

    Reply
  4. Jason Carreira

    I’m not sure that’s true… there’s value in a command pattern implementation that’s decoupled from direct method calls… Plus, XWork Interceptors give you access to XWork specific internals like the ActionInvocation.

    Results, etc, are more things XWork would add… Don’t let AOP blind you to the power of normal OOP ways of doing things.

    Reply
  5. Sam Newman

    Using Spring for some of the XWork internals would still give you a command pattern decoupled from direct method calls – in fact it would be possible to configure yourself which method got called on an Action to execute it for example, giving an even more abstract framework (the need for interfaces vanishes).
    Certainly XWork has value – it is a framework with a specific task that works well at what it does. Sure, someone could implement something similar using Spring on its own, but they would still have to supply the higher level mappings to make it as easy to use as XWork. I still think that by using Spring internally, you would be left with a system with the same API as now, but with more flexibility. Spring can handle Action and Result invocation, and handle interceptors, and to get the full benifit out of integrating with Spring this would make sense. The question is, is this added flexibility worth coupling XWork to another framework (be it Spring or Pico or…), or is it worth the reimplementation work.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Basic HTML is allowed. Your email address will not be published.

Subscribe to this comment feed via RSS

%d bloggers like this: