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

Combine multiple application contexts

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.

Share:

Ramkumar Ramalingam, Software Developer, IBM  

Ramkumar RamalingamRamkumar Ramalingam is an Advisory Software Engineer at the IBM India Software Lab in Bangalore, India. He is a Committer and Management Committee member on the Apache Tuscany project, and a member of the OASIS SCA Java Specification Community. You can contact Ramkumar at ramkumar_rj@in.ibm.com.


developerWorks Contributing author
        level

22 December 2009

Also available in Russian

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)
publicclass 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
    publicvoid setAddService(AddService addService) {
        this.addService = addService;
    }
    
    public AddService getAddService() {
        return addService;
    }

    publicvoid setSubtractService(SubtractService subtractService) {
        this.subtractService = subtractService;
    }
    
    public SubtractService getSubtractService() {
        return subtractService;
    }    
    
    @Reference(name="divideService")
    publicvoid setDivideService(DivideService divide) {
        this.divide = divide;
    }
    
    public DivideService getDivideService() {
        return divide;
    }
    
    publicvoid setMultiplyService(MultiplyService multiply) {
        this.multiply = multiply;
    }
    
    public MultiplyService getMultiplyService() {
        return multiply;
    }
    
    @Property
    publicvoid 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

DescriptionNameSize
Calculator example source codeos-springsca2-spring-example.zip15KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


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