Skip to main content

Design and develop SCA components using the Spring Framework, Part 2: Advanced techniques using Apache Tuscany

Combine multiple application contexts

Ramkumar Ramalingam, Software Developer, IBM
Ramkumar Ramalingam
Ramkumar Ramalingam is a staff software engineer at IBM India Software Labs in Bangalore. He is a committer on Apache Tuscany and a member of the Apache Tuscany Project Management Committee. He is also a member of OASIS SCA Java Specification Community.

Summary:  In this "Design and develop SCA components using the Spring Framework" series, learn how Service Component Architecture (SCA) and the Spring Framework effectively combine to build distributed service applications. This article explores some of the advanced features supported by the Apache Tuscany runtime. Learn how multiple application contexts can be combined and used to implement your SCA component. An example walks you through SCA annotations used to explicitly declare the SCA services, references, and properties within your Spring bean classes.

View more content in this series

Date:  22 Dec 2009
Level:  Introductory
Also available in:   Portuguese

Activity:  6209 views
Comments:  

Introduction

Part 1 of this series outlines the benefits of combining SCA and Spring. You learned how to expose Spring beans as an SCA service and how to access SCA services and properties within your Spring applications.

This article explores some advanced features supported by the Apache Tuscany runtime. Learn how multiple application contexts can be combined and used as an implementation for your SCA component. SCA annotations can be used to explicitly declare the SCA services, references, and properties within your Spring bean classes. Download the source code for the calculator example.

The example in this article uses the Apache Tuscany SCA Java™ technology runtime V1.5.1. To run the example applications, you need to download the binary distribution of the Apache Tuscany SCA Java implementation.


Using multiple application contexts for your SCA component

In Part 1, you learned that a Spring application can be defined as an SCA component within the SCA composite (also known as SCDL) in the format shown in Listing 1.


Listing 1. SCA composite with a Spring component

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
      xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
      targetNamespace="http://calc"
      xmlns:c="http://calc"
      name="Calculator">

    <component name="CalculatorServiceComponent">
             <implementation.spring location="targetURI"/>
    </component>

</composite>
            

The location attribute of the <implementation.spring> element can specify the target URI to point to an archive file (JAR), a directory, or to a Spring application context file directly. In any case, when using the location attribute of the <implementation.spring> element, Apache Tuscany allows only one application context as the target application context to be used as the implementation of your SCA component.

To use multiple application contexts to implement your SCA component, Apache Tuscany allows you to do so by defining a ClassPathXmlApplicationContext (in Listing 3) bean in the target application context identified from the location attribute of the <implementation.spring> element in the SCA composite file. Listing 2 shows an example.


Listing 2. SCA composite with a Spring component

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
      xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
      targetNamespace="http://calc"
      xmlns:c="http://calc"
      name="Calculator">

    <component name="CalculatorServiceComponent">
             <implementation.spring location="beanRefContext.xml"/>
    </component>
</composite>
            


Listing 3. beanRefContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sca="http://www.springframework.org/schema/sca"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/sca 
       http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd">

     <bean class=” org.springframework.context.support.ClassPathXmlApplicationContext”>
	 <constructor-arg> 
                   <list> 
                          <value>context1.xml</value> 
                          <value>context2.xml</value> 
                          <value>context3.xml</value> 
                  </list> 
         </constructor-arg>
     </bean>
</beans>

The Apache Tuscany runtime was designed to treat all of the target application contexts, with exactly one bean definition with ClassPathXmlApplicationContext as the bean class, as a multiple application context scenario. The Tuscany runtime will then create a combined application context instance for the list of application context files identified from the constructor argument of the ClassPathXmlApplicationContext bean.

In the example in Listing 2, the target application context defined as an implementation for CalculatorServiceComponent is beanRefContext.xml. In a typical scenario (in a single application context scenario), the Tuscany runtime will create an application context instance for the beanRefContext.xml and use it as an implementation instance for the CalculatorServiceComponent.

In Listing 3, the beanRefContext.xml defines just one bean definition with ClassPathXmlApplicationContext as the bean class. This scenario is treated as a multiple application context scenario by the Tuscany runtime. The list of application context files (context1.xml, context2.xml, and context3.xml) identified from the constructor argument of the ClassPathXmlApplicationContext bean definition are combined to create an application context instance for use as an implementation instance for the CalculatorServiceComponent. Figure 1 shows an example.

For a multiple context scenario, each application context file identified from the constructor argument of the ClassPathXmlApplicationContext bean definition can have its own SCA service, reference, and properties declared either implicitly or explicitly.


Figure 1. SCA runtime with ClassPathXmlApplicationContext
Screenshot shows the SCA runtime with ClassPathXmlApplicationContext

For a single application context scenario, as discussed in Part 1, the Tuscany runtime tries to:

  • Introspect the target application context definition file to determine the declared SCA service, reference, and properties.
  • Create an SCAParentApplicationContext with appropriate Spring beans for all the SCA references and properties declared within the target application context.

Later, the instance for the target application context is created using org.springframework.context.support.GenericApplicationContext by declaring the SCAParentApplicationContext as its parent.

In a multiple application context scenario, as shown in Figure 1, the Tuscany runtime tries to:

  • Introspect the list of application context files (context1.xml, context2.xml, and context3.xml) identified from the constructor argument of the ClassPathXmlApplicationContext bean defined in the target application context to determine the declared SCA service, reference, and properties.
  • Create an SCAParentApplicationContext with appropriate Spring beans for all the SCA references and properties declared within the identified list of application context files.

Later, an org.springframework.context.support.ClassPathXmlApplicationContext instance is created for the identified list of application context files by declaring the SCAParentApplicationContext as its parent.

Support for a multiple application context scenario using the ClassPathXmlApplicationContext bean definition on the target application context is beyond the recommendations from the SCA Spring Component Implementation Specification V1.0.

Any ClassPathXmlApplicationContext bean definition identified within the hierarchy of application contexts, other than the one defined in the target application context, will be treated as a normal ClassPathXmlApplicationContext bean by the Spring runtime and will be handled accordingly.


SCA annotations for Spring beans

Apache Tuscany's support for SCA annotations within Spring beans is beyond the recommendations from the SCA Spring Component Implementation Specification V1.0 defined by OSOA.

In Part 1, you learned that you can explicitly declare the SCA services, references, and properties within your Spring application context file using the custom SCA namespace elements, such as <sca:service>, <sca:reference>, and <sca:property>. Similarly, the Apache Tuscany SCA runtime allows you to explicitly declare the SCA services, references, and properties within your Spring bean class using SCA annotations.

The SCA annotations for explicitly declaring the SCA services, references, and properties within your Spring bean class are described below.

org.osoa.sca.annotations.Service
Provides a means for you to control which Spring beans are exposed as SCA services. The @Service annotation is used on a Java class to specify the interfaces of the services provided by the implementation.
org.osoa.sca.annotations.Reference
Provides a way for you to declare the dependencies of a Spring bean on the services provided by other SCA components available within the composite. Accessing a service using reference injection is done by defining a field, a setter method parameter, or a constructor parameter typed by the service interface and annotated with an @Reference annotation.
org.osoa.sca.annotations.Property
Provides a means for you to declare the dependencies of a Spring application context on the settable properties offered by SCA component implementation. The @Property annotation is used to define an SCA property.

The following example shows how to use SCA annotations within your Spring bean class. The CalculatorComponent example, as discussed in Part 1, is used to demonstrate how to use SCA annotations.

The calculator.composite, as shown in Listing 4, defines the CalculatorComponent with its dependency on four other services: AddComponent, SubtractComponent, MultiplyComponent, and DivideComponent.


Listing 4. calculator.composite

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
      xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
      targetNamespace="http://calc"
      xmlns:c="http://calc"
      name="Calculator">

    <service name="CalculatorService" promote=”CalculatorComponent">
        <interface.java interface="calculator.CalculatorService"/>
        <t:binding.rmi host="localhost" port="8099" serviceName="CalculatorRMIService"/>
    </service>

    <component name="CalculatorComponent">
        <implementation.spring location="META-INF/spring/calculator-context.xml"/>        
        <reference name="addService" target="AddComponent" />
        <reference name="subtractService" target="SubtractComponent" />
        <reference name="multiplyService" target="MultiplyComponent"/>
        <reference name="divideService" target="DivideComponent" />
        <property name="message">HelloWorld</property>
    </component>

    <component name="AddComponent">
        <t:implementation.script script="calculator/AddServiceImpl.js"/>
    </component>

    <component name="SubtractComponent">
        <implementation.java class="calculator.SubtractServiceImpl"/>
    </component>

    <component name="MultiplyComponent">
        <implementation.java class="calculator.MultiplyServiceImpl"/>        
    </component>

    <component name="DivideComponent">
        <t:implementation.script script="calculator/DivideServiceImpl.groovy"/>
    </component>
</composite>
            

In the example, the CalculatorComponent is a Spring application that defines the business logic using Spring beans. Create an application context file called calculator-context.xml, as in Listing 5, which defines the business logic for the CalculatorComponent by setting the required dependencies as bean properties.


Listing 5. calculator-context.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sca="http://www.springframework.org/schema/sca"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/sca 
       http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd">

    <bean id="Calculator" class="calculator.CalculatorServiceImpl">        
        <property name="addService" ref="addService"/>
        <property name="subtractService" ref="subtractService"/>
        <property name="multiplyService" ref="multiplyService"/>
        <property name="divideService" ref="divideService"/>
    </bean>

</beans>
            

In Part 1, you learned that custom SCA namespace elements such as <sca:service>, <sca:reference>, and <sca:property> can be used within this application context file (see Listing 5) to declare the SCA services, references, and properties explicitly. Here, you learn how SCA annotations can be used within the CalculatorServiceImpl bean class as an alternate way to explicitly declare the SCA services, references, and properties. Listing 6 shows an example.


Listing 6. CalculatorServiceImpl.java

@Service(CalculatorService.class)
public class CalculatorServiceImpl implements CalculatorService {
    
    // setter injection
    public AddService addService;
    
    // field injection
    @Reference
    public SubtractService subtractService;
    
    // field injection (different reference and field name)
    @Reference(name="multiplyService")
    public MultiplyService multiply;  
    
    // setter injection (different reference and field name)
    public DivideService divide;  
    
    // setter injection
    public String message;

    @Reference
    public void setAddService(AddService addService) {
        this.addService = addService;
    }
    
    public AddService getAddService() {
        return addService;
    }

    public void setSubtractService(SubtractService subtractService) {
        this.subtractService = subtractService;
    }
    
    public SubtractService getSubtractService() {
        return subtractService;
    }    
    
    @Reference(name="divideService")
    public void setDivideService(DivideService divide) {
        this.divide = divide;
    }
    
    public DivideService getDivideService() {
        return divide;
    }
    
    public void setMultiplyService(MultiplyService multiply) {
        this.multiply = multiply;
    }
    
    public MultiplyService getMultiplyService() {
        return multiply;
    }
    
    @Property
    public void setMessage(String message) {
        this.message = message;
    }
    
    …
}
            

The @Service annotation, as shown above, implies that the CalculatorServiceImpl bean is exposed as a service using the CalculatorService as its service interface. For each service exposed by the beans, an equivalent <service/> element should be defined in the SCA composite (as shown in Listing 4).

The @Reference annotations, as shown in Listing 6, declare the dependencies of this bean class on the services provided by other SCA components available within the composite. In the example, the Calculator bean is dependent on the SCA services addService, subtractService, multiplyService, and divideService.

In the CalculatorServiceImpl bean, the dependency on addService and divideService is declared by defining a reference injection on the setter methods, whose parameter is typed by the corresponding service interface AddService and DivideService. The dependency on subtractService and multiplyService is declared by defining a reference injection on the fields typed by the corresponding service interface SubtractService and MultiplyService.

The @Property annotation, as shown in Listing 6, declares the dependency on the settable property offered by an SCA component by defining the @Property annotation on an appropriate setter method.

Recommendations

It is recommended that you use SCA annotations independently; do not mix with any Spring native annotations. It is also recommended that you use SCA annotations or custom SCA namespace elements, as discussed in Part 1, to explicitly declare the SCA services, references, and properties for your Spring application. Don't mix them together.


Using SCA bindings for Spring-based SCA components

Bindings are used by services and references. References use bindings to describe the access mechanism used to call a service, which can be a service provided by another SCA composite. Services use bindings to describe the access mechanism that clients, which can be a client from another SCA composite, have to use to call the service.

A component that uses Spring as its implementation technology can wire SCA services and references without introducing binding-related SCA metadata into the Spring configuration. The Spring context knows very little about the SCA environment. Hence, the Spring bean implementation remains the same as in the previous examples, but different bindings are chosen at the SCA composite level.

The Apache Tuscany runtime supports various bindings, such as Web services, JMS, HTTP, RMI, JSON RPC, EJB, and ATOM. All bindings supported by SCA can be used for Spring implementation, as the bindings are independent of Spring context.

Note that Apache Tuscany does not support asynchronous and conversational service programming on a Spring-based SCA component.


Conclusion

In this article, you learned that more than one application context can be combined and used as an implementation for your SCA component. The SCA runtime creates the target application context instance for a multiple application context scenario. You also learned how SCA annotations can be used to explicitly declare the SCA services, references, and properties within your Spring bean classes.

Together, SCA and Spring make a powerful combination. Spring provides the infrastructure to develop your components with increased productivity and runtime performance, while improving test coverage and application quality. SCA provides the necessary infrastructure to assemble and model your components based on a Service-Oriented Architecture. SCA lets your components expose services, wire service components together, and deal with heterogeneous distributed systems.



Download

DescriptionNameSizeDownload method
Calculator example source codeos-springsca2-spring-example.zip15KBHTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Ramkumar Ramalingam

Ramkumar Ramalingam is a staff software engineer at IBM India Software Labs in Bangalore. He is a committer on Apache Tuscany and a member of the Apache Tuscany Project Management Committee. He is also a member of OASIS SCA Java Specification Community.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=457111
ArticleTitle=Design and develop SCA components using the Spring Framework, Part 2: Advanced techniques using Apache Tuscany
publish-date=12222009
author1-email=ramkumar_rj@in.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers