Monday, December 23, 2013

Springify The Strategy Pattern - Part 2


I talked about how to implement strategy pattern in springapplication in my previous post. Here I want to show you how Spring Annotations can make our lives easier to implement these patterns.
Spring 2.5 version introduced way to configure the dependency injection using annotations. This eliminates all those XML files in an application that just defined beans and bean wiring. Now annotation allows you to configure these inside the bean (component).

Some of the annotations that I will be using were @Autowired, @Resource, @Component, @Service etc.
All right let’s get into the code, I will take the second approach from the previous article and configure it using annotation. The new configuration XML looks like this,

<context:component-scan base-package="xyz.xyz.strategy"/>

What happened to all bean definitions? What is this component scan?
Well annotation based configuration eliminated the bean definition in the XML. Instead we enable spring auto component scanning of components in the base package where it can scan, detect, instantiate and wire all these beans (components).

Now let’s look at the beans again. You will have to go back to your strategy implementation classes like RegularShippingCostStrategyImpl etc. and add @Service or @Component annotation to the class as shown below,
@Service
public class RegularShippingCostStrategyImpl implements ShippingCostStrategy {
//calculation code
}

@Service
public class PremiumShippingCostStrategyImpl implements ShippingCostStrategy {
//calculation code
}

@Service
public class PrimeShippingCostStrategyImpl implements ShippingCostStrategy {
//calculation code
}

 
Your ShippingCostService class with added annotation below,
@Service
public class ShippingCostService {
 
 @Autowired
 private ShippingCostContext shippingContext = null;
  
 public double calculateShipping(Item item, String memberStatus){
  double cost = shippingContext.calculateShipping(item, memberStatus);
     return cost;
 }
 
}

 
Now look at this strategy context class,
@Component
public class ShippingCostContext {
 
 @Autowired
 private PrimeShippingCostStrategyImpl primeShippingStrategy = null;
 
 @Autowired
 private PremiumShippingCostStrategyImpl premiumShippingStrategy = null;
 
 @Autowired
 private RegularShippingCostStrategyImpl regularShippingStrategy = null;
        
 public double calculateShipping(Item item, String memberStatus){
       double cost = 0.0;
       if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PRIME))
          cost = primeShippingStrategy.calculate(item);
       else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_PREMIUM))
          cost = premiumShippingStrategy.calculate(item);
       else if(memberStatus.equalsIgnoreCase(StrategyConstants.MEMBER_REGULAR))
          cost = regularShippingStrategy.calculate(item);
    
       return cost;
 }
   
}

Now run the same test to check this out.
The same can be achieved for the first approach as well by simply switching auto wire strategy implementation classes from strategy context class to service class.
About the third approach is not all required since spring auto scan and auto wire simplifies the implementation already. But in case if you are interested here is how you can do it.

<context:component-scan base-package="xyz.xyz.strategy"/>
   
<util:map id="strategies" map-class="java.util.HashMap">
       <entry>
         <key>
           <util:constant static-field=" xyz.xyz.strategy.StrategyConstants.MEMBER_REGULAR"/>
          </key>
            <ref bean="regularShippingCostStrategyImpl" />
         </entry>
         <entry>
             <key>
              <util:constant static-field=" xyz.xyz.strategy.StrategyConstants.MEMBER_PREMIUM"/>
             </key>
             <ref bean="premiumShippingCostStrategyImpl" />
         </entry>
         <entry>
             <key>
              <util:constant static-field=" xyz.xyz.strategy.StrategyConstants.MEMBER_PRIME"/>
             </key>
             <ref bean="primeShippingCostStrategyImpl" />
         </entry>
   </util:map>

The XML context will have to define the spring util Map with key and ref value as shown above. You will then have to Autowire the map into the strategy context like this,
@Service
public class ShippingCostContext {
 
 @Resource
 private Properties strategies;
 
 public double calculateShipping(Item item, String memberstatus){
        double cost = 0.0;
        if(strategies.containsKey(memberstatus)){
         ShippingCostStrategy shippingCostStrategy = (ShippingCostStrategy)strategies.get(memberstatus);
         if(shippingCostStrategy != null)
          cost = shippingCostStrategy.calculate(item);
        }
               
 return cost;
 }


That’s all, the strategy pattern is now spring annotated. The spring annotations are quite powerful and simplify the configuration.

Wednesday, January 30, 2013

Developing Webservices using Apache's CXF


First Thing First

In an attempt to break my silence for some time here I am planning to blog a series of articles that would talk about developing web services using CXF and Spring framework.
Most of this related to some of the work I did in the past and also one presentation earlier this year for CJUG (Chicgao Java Users Group) on Developing web services using Apache's CXF.
I am planning to kick of few more articles to cover following,

  • Leg work - Setting up a project, writing simple service, publish and test.
  • Advanced topics - introduce CXF invokers, interceptors etc.
  • Method level Validation using JSR 303, hibernate validators

Anyways I am providing links to my presentation and sample code used for the presentation for those who are more interested in the code rather than writings.
You can checkout the code from google code i.e git repository. These are maven projects and shouldn't be big deal in setting up with in your eclipse and running it.
There are 2 projects loanProcessingService and creditHistoryService available to download.
Once you download the source code, you could import the projects as maven projects in to the eclipse.
You could run maven clean install in the eclipse or through command prompt, it doesn't matter.
Find xyz.abc.xyz.local package in either of these projects, you could see client and server classes these would help you test services outside any container.
Simply run the server as java application, once server is ready run the client.

Now you can fire up your tomcat and publish these web applications.
The soap UI project xml file can be found at src/test/resources/soapui/xyz.xml.
Bring up the soap UI, import the project by pointing to the above xml, simply open up the request for the method and execute it.

That's all for now, have fun with code.

References
Here is my CJUG Presentation.
Checkout the source code from here.