Tuesday, February 26, 2008

Prototypes, Lookup Methods and Java Config With Spring...

Referencing a Prototype from a Singleton in Spring:

Sometimes in Spring, you need to create a one-time use instance that has state (a.k.a a prototype bean) from a Singleton object. Essentially, one would need to access a prototype for a number of cases, namely those where the Gang of Four Abstract Factory can be applied :

  • You have an object that requires complex construction

  • You have many potential implementations of an interface, and generic logic that applies to all of those implementations.

    Spring's documentation for prototype scope and method injection lets you know that you can accomplish that goal in the following manner:

    <!-- a stateful bean deployed as a prototype (non-singleton) -->
    <bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
       <!-- inject dependencies here as required -->
    </bean>
    
    <!-- commandProcessor uses statefulCommandHelper -->
    <bean id="commandManager" class="fiona.apple.CommandManager">
       <lookup-method name="createCommand" bean="command"/>
    </bean>

    where your commandManager looks something like:

    package fiona.apple;
    
    // no more Spring imports!
    `public abstract class CommandManager {
      public Object process(Object commandState) {
        // grab a new instance of the appropriate Command interface
        Command command = createCommand();
        // set the state on the (hopefully brand new) Command instance
        command.setState(commandState);
        return command.execute();
      }
    
      // okay... but where is the implementation of this method?
      protected abstract Command createCommand();
    }

    You have a generic business object/singleton (CommandManager) that need to create an implementation of an interface with state to perform some task.

    I personally found it useful for a couple of scenario in a large scale website projects. Overall, this approach served me well when I needed it, and was pretty painless.

    Constructive Criticism

    While the "lookup-method" trick is definitely useful, it definitely doesn't feel right. Bob Lee criticised Spring for having to put method names in XML (although I can't find a reference to the specific entry in which he does it). I don't know if the criticism was meant for this specific instance, but the criticism definite applies. This definitely feels like you're coding in XML. Programming in XML isn't pretty. The XML configuration in Spring is getting the more and more complex, although for now, it doesn't get to complicated.

    This coding through XML isn't purely a "feel" issue. What happens if you change the method name? Why should you have to wait until runtime to catch typos?

    Spring 2.5 theoretical @LookupMethod

    I don't think that the new Spring annotations solve the -> problem, but I assume that it could. Here's how it could look:

    package fiona.apple;
    
    // no more Spring imports... except for spring annotations
    
    @Component
    public abstract class CommandManager {
      public Object process(Object commandState) {
        // grab a new instance of the appropriate Command interface
        Command command = createCommand();
        // set the state on the (hopefully brand new) Command instance
        command.setState(commandState);
        return command.execute();
      }
    
      @LookupMethod(beanName="command")
      protected abstract Command createCommand();
    }

    This has a lot of advantages: it's very terse and shows you all about how a class is used right along with the implementation of the class. The disadvantage here, is that you're adding dependencies on Spring via the annotations. Also, you can't configure different instances of the "Singleton" with different implementations of the prototype... (I'm not sure what to call the multi-Singleton... Multiton?)

    Spring JavaConfig's approach

    I've been thinking about and even working on Spring JavaConfig (SJC) for a while. Take a look at this SJC bug that talks about lookup methods. The way you'd implement "lookup methods" in a java oriented environment is quite straight forward. The bean stays the same:

    package fiona.apple;
    
    // no more Spring imports!
    public abstract class CommandManager {
      public Object process(Object commandState) {
        // grab a new instance of the appropriate Command interface
        Command command = createCommand();
        // set the state on the (hopefully brand new) Command instance
        command.setState(commandState);
        return command.execute();
      }
    
      // okay... but where is the implementation of this method?
      protected abstract Command createCommand();
    }

    The configuration code is surprisingly simple:

    package fiona.apple;
    
    // a whole bunch of spring and business object imports
    
    @Configuration
    public class CommandManagerConfiguration {
    
       @Bean
       public CommandManager commandManager(){
          return new CommandManager(){
             protected Command createCommand(){
               /* you can add your dependencies here,
                  if you have any */
                return new AsyncCommand();
             }
          };
       }
    
    }

    A Java based configuration is, IMHO, a much more natural implementation than the XML approach. This is a surprisingly trivial implementation of a relatively complicated scenario.

    The slickness here comes from writing simple Java code

    SJC beyond prototypes

    The prototype slickness lead me down a path that helped me shed the preconceived notions that came from XML-based development. I started thinking about where I could use java to make my application configuration process even better. Now, I definitely thought of some cool infrastructure stuff that I could add to Spring JavaConfig, but that's not the application configuration ingredients that I find most interesting.

    The most interesting techniques a programmatic environment can add to application construction come from really simple day-to-day java code. For example, you can create conditional beans using a simple "if" statement. You can concatenate Lists and Maps. Those examples, plus other simple programming techniques that we've come to depend on as second nature, are now available. Spring doesn't dictate what I can do when constructing an application. You can now use Plain Old Java to configure your Plain Old Java Objects.

    Some of the more esoteric techniques I thought of included 1) finding an easy hook that allows programmatic bean creation using Spring's underlying application configuration meta data objects, and 2) allowing users to hook in their own configuration Annotations.

    Conclusions

    I hope that this blog entry will be useful for two purposes:

    1. Describe how and why Spring creates prototype objects within singleton beans

    2. Give an idea about how Spring JavaConfig can help with

    You'll see some fantastic things from Spring JavaConfig soon... In the mean time, there's definitely plenty of goodies that you can get out of traditional, and main-stream spring xml configuration and java annotations.

    By Solomon

  • Sunday, February 24, 2008

    Spring WS marshalling framework

    Talking about WebServices from a clients perspective, Spring WS provides some true simplifications when it comes to configuring and calling arbitrary Services. While emphasizing a contract-first view (with a clear focus on the schema of the request resp. response message payload), it supports a couple of ways to map an object graph to the stipulated message structure of the contracted request schema (marshalling) and of course vice versa, mapping the received response payload to an appropriate object structure (unmarshalling). The following sections will give some demonstration on how to leverage the various options for marshalling and unmarshalling within Spring WS, especially by showing how to apply a strategy for marshalling and a different one for unmarshalling, all within the same WebService call.

    WebServiceGatewaySupport

    Spring WS encourages a client model that’s based on the Gateway ‘pattern’: A (Message-) Gateway encapsulates the technical API code that is necessarily used to access an external resource (in our case a WebService), so a client of that Service is shielded from the technical complexity behind. For that purpose you can simply extend org.springframework.ws.client.core.support. WebServiceGatewaySupport and pick one of the provided send…() methods:

    public class FundRatingGateway extends WebServiceGatewaySupport {
     …
     public Rating rate( Fund fund) throws IOException{
       …
       … getWebServiceTemplate().sendSourceAndReceive( … );
       …
     }
    }

    As you have seen, we can rely on a org.springframework.ws.client.core.WebServiceTemplate that’s provided automatically by WebServiceGatewaySupport, assumed that it’s configured properly in Springs appclication context. Most important, you have to provide the URI of the targeted WebService. Since you don’t need to modify or change the URI during runtime, you can provide a static URI simply by injecting it to a property called defaultUri:

    <bean id=”fundRatingGateway” class=”demo.webservice.FundRatingGateway”>
       <property name=”defaultUri” value=”http://www.xxx.org/demo/ws/fundrating/”/>
       …
    </bean>

    Further on, you could also inject a certain message factory (to a property of the same name), which is responsible for creating the message (by selecting the underlying kind of message representation, i.e. generating a SOAP envelope if using SOAP messages). So if you for example want to produce SOAP messages using SAAJ (SOAP with Attachements API), nothing further is to do since this is the default message factory that’s being used by WebServiceGatewaySupport.

    Automated Marshalling and Unmarshalling

    Assumed, that we initially don’t want to create and parse XML manually in order to convert a Fund into XML and the received XML of the calculated Rating back into a Rating instance (although possible with Spring WS), we can endue WebServiceGatewaySupport with an arbitrary instance of a Marshaller and Unmarshaller, as long as they implement org.springframework.oxm.Marshaller resp. org.springframework.oxm.Unmarshaller. That said, it’s quite possible to assign a CastorMarshaller to transform the request object(s) to XML and a JAXB Unmarshaller for the way back (there are some Implementations right at hand, i.e. also basing on JIBX or XStream, although you could come up with your own implementation of a Marshaller or Unmarshaller), it’s only a question of configuration:

        <bean id=”fundRatingGateway” class=”demo.webservice.fundrating.FundRatingGateway”>
           <property name=”defaultUri” value=”http://www.xxx.org/demo/ws/fundrating/”/>
           <property name=”marshaller” ref=”castorFundMarshaller” />
           <property name=”unmarshaller” ref=”jaxbRatingUnmarshaller” />
       </bean>
    
       <bean id=”castorFundMarshaller” class=”org.springframework.oxm.castor.CastorMarshaller”>
     <property name=”mappingLocation” value=”classpath:demo//webservice/fundrating/FundRequestMapping.xml” />
       </bean>

    Now all you have to do is call marshalSendAndReceive() on WebServiceTemplate - it will use the injected instances of marshaller and unmarshaller for conversion between the objects view and the messages view. All the boilerplate work of conversion and message construction will going on behind the scenes:

    public class FundRatingGateway extends WebServiceGatewaySupport {
     …
     public Rating rate( Fund fund) throws IOException{
       return (Rating) getWebServiceTemplate().marshalSendSourceAndReceive( Fund );
     }
    }

    In the Mix

    Now suppose another scenario: The mesage structure of the returned response (the calculated Rating) might be too complex to be handled easily by an Unmarshaller (i.e. would the resulting mapping file be way to complex and uncomprehensable or there may be some rather dynamic parts within the responses schema that’s better handled programmatically and therefore with greater flexibility). In such cases it may be for example better to parse the resulting DOM structure of the response message (while we want to continue with marshalling the rather easy structured Fund using a Marshaller). We can’t use marshalSendSourceAndReceive() any longer since it requires both - a Marshaller and an Unmarshaller, so we have to look for an alternative.

    Let’s take a closer look at WebServiceTemplates ’standard’ method for calling a WebService: sendSourceAndReceive( javax.xml.transform.Source requestPayload, org.springframework.ws.client.core.SourceExtractor responseExtractor )

    It doesn’t seem to be a good candidate for our scenario at first sight, since there seems to be no way to introduce our Marshaller (though there seems to be a good chance for parsing the DOM of the response as we only have to act as a SourceExtractor - but one step after another).

    Marshalling … engage

    First we have to bring the Marshaller back into the game. We need the Marshaller to produce a javax.xml.transform.Source that we could pass as first argument. Inspecting org.springframework.oxm.Marshaller, we can see that there’s only one method responsible for the transformation:

    public void marshal( java.lang.Object, javax.xml.transform.Result )

    The second argument seems to be of type in-out, so the problem shifts to the question on how to convert Result to Source. Luckily there’s only a short distance between those two - we’ll using org.springframework.xml.transform.StringResult that gets wrapped (indirectly via org.springframework.core.io.ByteArrayResource) into a org.springframework.xml.transform.ResourceSource. It reads more complex than it’s actually is - take a short look at the source and you’ll understand immediately:

    public class FundRatingGateway extends WebServiceGatewaySupport {
    …
     private Source marshall( Fund fund ) throws IOException{
    
      StringResult result = new StringResult();
    
      getMarshaller().marshal( fund, result );
    
      return new ResourceSource( new ByteArrayResource( result.toString().getBytes() ) );
     }
    }

    Unmarshalling … extract

    Now, the only thing left is to come up with an implementation of org.springframework.ws.client.core.SourceExtractor that is capable of transforming the response message back into a Rating instance. We have to implement public Object extractData( javax.xml.transform.Source ) and see that again an instance of Source has a finger in the pie, this time representing the response. Since the delivered Source is an instance of javax.xml.transform.dom.DOMSource, we could easily parse the Document by relying on the DOM API:

    public class RatingResponseExtractor implements SourceExtractor{
    
     public Object extractData( Source src ) throws IOException, TransformerException {
    
      DOMSource dom = (DOMSource) src;
    
      return toRating( dom.getNode() );
     }
    
           private Rating toRating( Node ratingRootNode ){
               …
           }
           …

    Putting the pieces together

    Having all essential ingredients on board, it’s easy to adapt our Gateway. We simply use the converted Source that’s generated by our Marshaller and an instance of RatingResponseExtractor in order to please WebServiceTemplate and that’s it. Note, that we have to cast the result of RatingResponseExtractor since the interface of SourceExtractor forced us to return an Object.

    public class FundRatingGateway extends WebServiceGatewaySupport {
       private SourceExtractor ratingResponseExtractor = new RatingResponseExtractor();
       …
       public Rating rate( Fund fund) throws IOException{
           return
               getWebServiceTemplate()
                   .sendSourceAndReceive( marshal( fund ), ratingResponseExtractor  );
       }
       …
    }

    Conclusion

    As you may have seen, marshalling and unmarshalling isn’t very painful within Spring WS, especially if using WebServiceGatewaySupport in conjunction with its provided WebServiceTemplate. It’s easy to use any kind of Marshaller or Unmarshaller as long as they appear as org.springframework.oxm.Marshaller resp. Unmarshaller. Even mixing different transformation strategies for request and response messages is possible - of course also possible the other way round: providing a Source instance as response payload from a constructed DOM Document should just as well be possible as using an Unmarshaller for the response message at the same time. Since org.springframework.oxm.Unmarshaller.unmarshal() accepts directly an instance of Source, there’s even no conversion required.

    By Mario Gleichmann