After the Open SOA (OSOA) initiative published the white paper titled "Power Combination: SCA, OSGi and Spring," the combination of the three technologies has generated some interest. Spring Dynamic Module, a commercial implementation of such an infrastructure, combines Spring and OGSi. Spring beans can be used as a Service Component Architecture (SCA) component implementation. Apache Tuscany's Java implementation was built on Apache's OSGi framework (Felix).
In this series, learn how to design and develop SCA components using the Spring Framework and the Apache Tuscany SCA Java runtime. Examples and code snippets help explain the benefits of combining SCA and Spring. You will also learn how SCA and Spring combine to build distributed services applications.
This article covers some basic design principles you'll need to know while developing SCA components using Spring. You'll explore how to expose Spring beans as an SCA service, and how to access SCA services and properties within your Spring applications.
Part 2 delves into advanced features, such as handling multiple application contexts with SCA and using SCA annotations within your Spring beans.
Download the example source code. The example is designed to run with the Apache Tuscany runtime, but the focus is not on developing SCA components. This article highlights how to use the Spring application as an implementation technology for your SCA components.
This article discusses the following programs.
- SCA
- Provides a programming model for building applications and solutions based
on a Service-Oriented Architecture (SOA). SCA is based on the idea that business
function is provided as a series of services assembled
to create solutions that serve a particular business need. These composite
applications can contain new services created for the
application and business function from existing systems, and
applications reused as part of the composition. SCA provides:
- A model for the composition of services and for the creation of service components, including reuse of existing application function within SCA composites.
- Flexible composition, reuse, technology, and deployment choices that make it an ideal environment in which to build a heterogeneous distributed system.
- Support for multiple implementation languages and communication mechanisms.
- A simplified component programming model for implementation of business services using any of a variety of technologies, such as Enterprise JavaBeans, Java POJOs, Spring beans, BPEL Process, COBOL, C++, PHP, etc.
- Spring Framework
- Commonly called Spring, it is an open source project that tries to make the J2EE environment more accessible by addressing the complexity of enterprise application development. A chief advantage of Spring is its layered architecture. It lets you be selective about which of its components you use, while providing a cohesive framework for J2EE application development. Spring provides a framework for simple Java objects, enabling them to use the J2EE container via wrapper classes and XML configuration. Spring's objectives are to deliver significant benefits to projects by increasing development productivity and runtime performance, and to improve test coverage and application quality. Spring is often described as a lightweight container environment, though it's probably more proper to call it a framework for simplifying development.
- Apache Tuscany
- The open source Apache Tuscany project is dedicated to implementing the SCA Specifications (and other SCA specifications, such as Service Data Objects (SDO) and Data Access Service (DAS)). Apache Tuscany provides a complete infrastructure for the SCA runtime complying with the Open Service-Oriented Architecture (OSOA) and advancing open standards for the global information society (OASIS SCA Java) specifications. The examples in this article use V1.5, which was the latest as of this writing. To run the example applications, download the binary distribution of Apache Tuscany SCA Java implementation.
A basic artifact of SCA is the component, which is the unit of construction for SCA. A component consists of a configured instance of an implementation, where an implementation is the piece of program code providing business functions. The business function is offered for use by other components as services. Implementations can depend on services provided by other components. These dependencies are called references.
Implementations can have settable properties, which are data values that influence the operation of the business function. The component configures the implementation by providing values for the properties and by wiring the references to services provided by other components. More than one component can use and configure the same implementation, whereas each component configures the implementation differently.
SCA allows for:
- A variety of implementation technologies, such as Java POJOs, EJBs, Spring beans, BPEL Process, COBOL, C++
- Scripting languages, such as PHP and JavaScript
- Declarative languages, such as XQuery and SQL
SCA describes the content and linkage of an application in assemblies called composites, as shown in Figure 1. Composites can contain components, services, references, property declarations, and the wiring that describes the connections between these elements. Composites can group and link components built from different implementation technologies, allowing appropriate technologies to be used for each business task. Composites are deployed within an SCA domain.
Figure 1. SCA composite diagram
The SCA Assembly Model consists of a series of artifacts that define the configuration of an SCA domain in terms of composites that contain assemblies of service components, and the connections and related artifacts that describe how they are linked. The SCA Assembly Model Specification has more details (see Resources).
Benefits of combining SCA and Spring
The Spring Framework and SCA share many design principles. SCA views Spring as a partner that can be used as an implementation technology for its components. The SCA Spring Component Implementation Specification defines how Spring is used in this way.
Similar to a Spring bean, an SCA component can contain references to services supplied by other components, and it can have configurable properties. In contrast to Spring, SCA is a cross-language, distributed component architecture supporting multiple communication mechanisms among components. SCA may be used to extend the capabilities of Spring components by publishing Spring beans as services accessed by other remote components and providing Spring beans with service references wired to services of other, potentially remote, components.
An effective way to combine SCA and Spring is to use Spring to build implementations of "coarse-grained" service components and bring in SCA to expose services, wire service components together, and deal with heterogeneous and distributed systems. SCA can add useful capabilities to an application implemented using Spring, such as:
- Extended support for remote components and multiple protocols
- Support for components written in a variety of programming languages beyond those supported on the JVM
- Support for WS-Policy specified policies for capabilities like security and transactions
Ease of testing components is one great feature of Spring. The lack of APIs and the injection technique let you test with simple mock objects. SCA complements this in the services arena, since the SCA composition surrounding a service component can easily be switched to a mock configuration for testing.
Defining a Spring application as an SCA component
In Apache Tuscany SCA implementation, SCA uses Spring as an implementation technology for its components within the SCA composite. A Spring application can be defined as an SCA component within the SCA composite, also known as SCDL, in the format shown below.
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) or a
directory or to a Spring application context file directly.
The following list shows examples of the possible ways you can specify the target URI for the
<implementation.spring> location attribute.
- Specifying a Spring application context file
-
<implementation.spring location="application-context.xml"/>
- Specifying a directory
-
<implementation.spring location="./spring"/>
The target URI specifies the resource as a directory namedspring, where all the Spring-related files are available. A META-INF/MANIFEST.MF file must exist underneath the Spring directory, which specifies the path to the context configuration file using the headerSpring-Contextof the formatSpring-Context ::= <path>, wherepathis relative to the Spring directory. If there is no MANIFEST.MF file or no Spring-Context header within the MANIFEST file, the default behavior is to build an application context using the application-context.xml file in the META-INF/spring directory available within the target Spring directory. - Specifying an archive file
-
<implementation.spring location="spring.jar"/>
The target URI specifies the resource as an archive file named spring.jar, where all the Spring-related files are available. A META-INF/MANIFEST.MF file must exist in the spring.jar archive file, which specifies the path to the context configuration file using the headerSpring-Contextof the formatSpring-Context ::= <path>., wherepathis pointing to a file within the spring.jar archive. If there is no MANIFEST.MF file or no Spring-Context header within the MANIFEST file, the default behavior is to build an application context using the application-context.xml file in the META-INF/spring directory available within the target spring.jar archive file.
The business function of a component implementation is offered for use by other components as services. Implementations can depend on services provided by other components; these dependencies are called references. Implementations can have settable properties, which are data values that influence the operation of the business function. The following example shows how Spring beans can be offered as an SCA service, and how to configure SCA references and SCA properties within your Spring application context.
Let's use the example of a CalculatorComponent, as
shown in Figure 2. It has external dependencies on other components
(AddComponent, SubtractComponent, MultiplyComponent, and
DivideComponent) to achieve the desired functions. In this example,
the business function of the CalculatorComponent is implemented
using Spring beans, AddComponent using JavaScript, SubtractComponent and
MultiplyComponent using simple POJOs, and the
DivideComponent using
Groovy script.
Figure 2. Spring-based
CalculatorComponent
The next step is to create an SCA composite called calculator.composite, as shown in Listing 2, to define the components, services, references, property declarations, and wiring that describe the connections between these elements. See Download for this example.
Listing 2. 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">
<component name="CalculatorComponent">
<implementation.spring location="META-INF/spring/calculator-context.xml"/>
<service name="CalculatorService">
<interface.java interface="calculator.CalculatorService"/>
<t:binding.rmi host="localhost" port="8099"
serviceName="CalculatorRMIService"/>
</service>
<reference name="addService" target="AddComponent" />
<reference name="subtractService" target="SubtractComponent" />
<reference name="multiplyService" target="MultiplyComponent"/>
<reference name="divideService" target="DivideComponent" />
</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>
|
The calculator.composite defines the
CalculatorComponent with its dependency on four
other services, such as
AddComponent, SubtractComponent, MultiplyComponent, and
DivideComponent,
using the <reference> element. They are implemented using
different technologies. AddComponent provides the
implementation for addService, which returns addition of two numbers given
as input. Similarly, SubtractComponent provides the implementation for
subtractService, which returns subtraction of
two numbers.
MultiplyComponent provides the implementation
for multiplyService, which
returns the multiplication of two numbers. DivideComponent provides the
implementation for divideService.
You probably noticed that in calculator.composite that AddComponent, SubtractComponent, MultiplyComponent, and
DivideComponent do not expose
any services explicitly using the <service> element (as in
the way the example declared to expose CalculatorService for the
CalculatorComponent). In such cases, when your SCA components do not
expose any services explicitly using the <service> element,
the SCA runtime by default will expose your component to be assessed
using a default binding called binding.sca. Similarly, in your
CalculatorComponent, you can just ignore
specifying any specific binding
information for the references to these components. The SCA
runtime provides a default binding, binding.sca, to wire the
components together. The
SCA Assembly Model Specification has more about
binding.sca.
In the example, the CalculatorComponent is a Spring application that
defines the business logic using Spring beans. It's important to
remember to declare the required SCA dependencies appropriately in
your Spring application context definition file.
Create a Spring application context definition file named
calculator-context.xml. As shown in Listing 3, it provides the
business logic for the CalculatorComponent by declaring the required beans
and their dependencies to achieve the required functions.
Listing 3. 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="
|
In the calculator-context.xml file, the calculator bean defines the
business logic for the CalculatorComponent by setting the required
dependencies as bean properties. For a Spring bean, each property is
an actual definition of the value to set or a reference to another
bean in the container. In the example, the calculator bean is dependent
on various SCA services offered by components within the
composite, so the properties should be set to reference (set the
value of the ref attribute) the SCA references defined in the
calculator.composite. Since the goal is to expose the
CalculatorComponent as a service, you should also remember to declare
which bean needs to be exposed for the SCA service defined in the
calculator.composite.
The Spring component implementation specification and Apache Tuscany SCA runtime lets you declare the SCA references and properties as bean properties. You can also declare the bean to be exposed as SCA services, either explicitly or implicitly, as explained below.
Declaring explicit SCA services, references, and properties
The SCA Spring Component Implementation Specification and Apache Tuscany SCA runtime allow you to declare the SCA services, references, and properties within your Spring application context file using the custom SCA namespace elements defined in the Spring SCA schema. You can use the custom SCA namespace elements to declare Spring beans as SCA services, and to define references to SCA services and properties obtained via the SCA component definition. Using SCA namespace elements within your Spring application context file is called explicit declaration of SCA services, references, and properties.
The custom SCA namespace elements for declaring the SCA services, references, and properties within your application context file are explained below.
<sca:service>- Provides a means for you to control which Spring beans are exposed as SCA services. The SCA runtime is responsible for creating the proper service bindings and applying required policies to those services based on SCDL configuration.
<sca:reference>- Provides a means for you to declare the dependencies of a Spring application context on the services provided by other SCA components available within the composite. The SCA runtime is responsible for creating the proper reference bindings and applying required policies to those services based on SCDL configuration.
<sca: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
nameattribute of the<sca:property>element should have a matching SCA property declared in the composite for its containing component.
Declare the SCA service, reference, and properties within your calculator-context.xml (in Listing 3) using the custom SCA namespace elements, as shown below.
Listing 4. 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="
|
The <sca:service> element, as shown in
Listing 4,
declares to offer CalculatorService as an SCA service from the
target calculator bean. The required name attribute should
have the same value as the name of the <service> element
defined for the CalculatorComponent in the
calculator.composite. The
required type attribute should declare the type
of service as
the fully qualified name of a Java class. The required target
attribute should have the name of a <bean/> element within
the application context that provides the service declared by this
<sca:service> element.
The <sca:reference> elements in Listing 4
declare the dependencies of this application context on the services
provided by other SCA components available within the composite. In the
example, the calculator bean is dependent on the SCA services,
such as
AddComponent, SubtractComponent, MultiplyComponent, and
DivideComponent.
These dependencies are declared using the <sca:reference>
elements. The required name attribute of
this element should have the same value as the name of the
<reference> element defined for the
CalculatorComponent in
the calculator.composite. The required type attribute should
declare the type of the service as the fully qualified name of a Java
class. For each <reference> element found in the
CalculatorComponent of the calculator.composite, an equivalent
<sca:reference> element is declared in
the Spring
application context.
Similarly, the <sca:property> element allows you to
declare the dependencies of this application context on the SCA properties
offered via the CalculatorComponent in the
calculator.composite.
The required name attribute should have the
same value as the name of
the <property/> element defined for the
CalculatorComponent
in the calculator.composite (as shown in Listing 2).
The required
type attribute should declare the type of property as the
fully qualified name of a Java class.
Declaring implicit SCA services, references, and properties
The SCA Spring Component Implementation Specification and Apache Tuscany SCA runtime allow you to declare the SCA services, references, and properties within your Spring application context file directly, without using any custom SCA namespace elements defined in the Spring SCA schema. The direct use of SCA references and properties within your Spring application context file, without custom SCA namespaces, is called implicit declaration of SCA services, references, and properties. The calculator-context.xml in Listing 3 is an example.
The SCA references, as defined in the calculator.composite file (see
Listing 2), with names such as
addService, subtractService, multiplyService, and
divideService,
can be directly used as bean references within your Spring
application context (as in Listing 3). The calculator
bean properties can be set to reference (set the value of the ref
attribute) the SCA references defined in the calculator.composite (Listing 2) directly by using the SCA reference name. In such
cases, the type of the bean references will be introspected by Tuscany
runtime from the bean class definition to validate and match it with the
type of SCA references defined in the composite.
Similarly, the SCA
properties defined in the SCA composite can be directly used as bean
references within your Spring application context. Set the bean
properties (set the value of the ref attribute) to reference
the SCA properties defined in the calculator.composite by using the SCA
property name.
When there is no explicit <sca:service> element in the
application context, all the top-level beans will be exposed as SCA
services using the bean name as the service name. Any inner beans or
abstract beans will not be considered for implicit service creation.
When a Spring bean implementation class implements more than one interface,
these beans can be exposed as a single service or as multiple
services. You use explicit <sca:service>
elements, where each <sca:service> element references the
same <bean> element, but the type attribute
uses only one of the interfaces provided by the bean. In the case of implicit
service creation, the bean is exposed as a single service by declaring the
bean class itself as an interface for the service.
Though usage of implicit SCA services, references, and properties is supported in the Apache Tuscany SCA runtime, there are a few scenarios where the implicit declarations would not work appropriately.
Scenario 1. Using implicit SCA references and properties for collections
In Spring, the <list/>,
<set/>,
<map/>, and
<props/> elements allow
properties and arguments of the Java Collection
type List, Set,
Map, and Properties,
respectively, to be defined and set. The sample bean definition,
as shown in Listing 5, demonstrates the limitations of using implicit SCA
references and properties within the
<list/>,
<set/>, and
<map/> elements of Spring.
Listing 5. Implicit SCA references for collections
<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="mySCAReference1" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry>
<key>
<value>an entry</value>
</key>
<value>just some string</value>
</entry>
<entry>
<key>
<value>a ref</value>
</key>
<ref bean="mySCAReference2" />
</entry>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="mySCAReference3" />
</set>
</property>
</bean>
|
Assume that the bean implementation for the bean property called
someList is defined as in Listing 6. The
List is
declared as generic to accept any kind of Java class in its
collection.
Listing 6. Bean implementation for
someList property
private List<?> someList;
public List<?> getSomeList() {
return someList;
}
public void setSomeList(List<?> someList) {
this.someList = someList;
}
|
In this scenario, the Apache Tuscany runtime would not be
able to introspect the exact type of the SCA reference (the
type of mySCAReference1,
mySCAReference2, and
mySCAReference3) object required for this collection. The
required SCA reference injection would fail. The same rule applies to
the someMap and someSet properties when they are declared
to accept any kind of Java class in their collections. It is advised that
you always
explicitly declare the SCA references using the
<sca:reference> element with the required
name and type
attribute for such scenarios.
Scenario 2. Using implicit SCA references and properties for constructor injection
Constructor injection in Spring lets you inject your dependencies
through class constructors. To reduce
potential ambiguities, Spring recommends using the index
and type attributes appropriately for the
<constructor-arg> element whenever there are
multiple constructors defined in your bean implementation.
Tuscany also recommends using the index and type
attributes for the <constructor-arg> element, and declaring the dependent SCA references explicitly for all the
constructor injection scenarios, even if your bean has only one
constructor.
For example, assume you're trying to inject the required dependencies (the required SCA references) for the calculator bean using the constructor. You should define your bean definition as shown in Listing 7. Using implicit SCA references and properties are not supported for constructor injection in Tuscany.
Listing 7. Constructor injection for calculator bean
<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
|
Application context creation in the SCA runtime
In Spring, the primary unit of modularity is an application context, which contains some number of beans (objects managed by the Spring application context). Application contexts can be configured in a hierarchy where a child application context can see beans defined in a parent, but not vice versa.
By default, the Spring container validates the configuration of each bean as the container is created, including the validation that properties which are bean references are actually referring to valid beans. For a Spring application context that contains references to SCA references and properties, it is the responsibility of the SCA runtime to create valid beans for all the SCA references and properties used within the Spring application context. Then, the Spring container can validate the beans and load the application context successfully. See Figure 3 for an example.
Figure 3. SCA runtime with parent context
The Tuscany runtime uses Spring Binary V2.5.5 to load and run the target
application context specified in the location attribute of the
<implementation.spring> element defined in the
calculator.composite file (as shown in Listing 2). Before the target
application context is loaded, the Tuscany runtime tries to:
- Introspect the target application context definition file to determine the declared SCA service, reference, and properties within your Spring application context
- Create a
SCAParentApplicationContextwith appropriate Spring beans for all the SCA references and properties declared within your target application context.
In the example, an SCAParentApplicationContext is
created with the appropriate Spring bean for all the SCA references, such
as addService, subtractService, multiplyService, and divideService,
declared in the calculator-context.xml file (see Figure 3). Later,
the target application context is created using
org.springframework.context.support.GenericApplicationContext by
declaring the SCAParentApplicationContext as its parent.
The Tuscany runtime also provides necessary infrastructure to create proper service bindings, and applies required policies to those services implemented using Spring beans based on SCDL configuration.
In this article, you learned how to design and develop your SCA components using Spring-based applications. You can now declare SCA services, references, and properties explicitly within your Spring application context using custom SCA namespace elements, and can declare the SCA references and properties directly within your Spring application context. You explored how the SCA runtime creates the target application context for your SCA component. Using examples, the article briefly touched on the limitations of using implicit SCA references and properties within your application context.
Together, SCA and Spring are a powerful combination. Spring provides the infrastructure to develop your components with increased productivity and runtime performance, and also improves test coverage and application quality. SCA provides the necessary infrastructure to assemble and model your components based on an SOA by allowing your components to expose services, wire service components together, and to deal with heterogeneous distributed systems.
Stay tuned for Part 2, which will tackle advanced features, such as handling multiple application contexts with SCA and using SCA annotations within your Spring beans.
| Description | Name | Size | Download method |
|---|---|---|---|
| Calculator example source code | os-springsca1-spring-example.zip | 7KB | HTTP |
Information about download methods
Learn
- Read about
Apache Tuscany, a
comprehensive infrastructure for SOA development and management based
on SCA standards.
- Learn all about the
Spring Framework.
- Read more about the Open Service-Oriented Architecture (OSOA) project.
- Learn about OASIS SCA
Java, an open CSA technical committees for SCA.
-
"Introducing SCA"
covers fundamentals, SCA
components, policy, and how to put the pieces together.
-
The whitepaper "Power
Combination, SCA, OSGi and Spring" examines why SCA, OSGi, and Spring should be
considered complementary technologies; different possibilities and ways
to combine SCA with OSGi and Spring; advantages of combining SCA,
OSGi, and Spring; and ongoing activities intended to make the combination a reality.
- Spring Dynamic Modules
make it easy to build Spring applications that run in an OSGi
framework.
- Read the SCA Assembly
Model Specification (OSOA specification on the SCA assembly model).
-
Learn more from the SCA Spring Component Implementation Specification.
- Look at the Spring SCA schema, part of
the OSOA specification on the SCA Spring Component Implementation
to declare SCA elements in Spring.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Stay current with developerWorks' Technical events and webcasts.
-
Follow developerWorks on Twitter.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products, as well as our most popular articles and tutorials.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
Get products and technologies
- Get Apache Felix, a
community effort to implement the OSGi R4 Service Platform.
- Download
the binary distribution of Apache Tuscany SCA Java
implementation.
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
- Download
IBM product evaluation versions
or explore
the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from
DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
Discuss
-
Participate in developerWorks blogs and get involved in the developerWorks community.
Comments (Undergoing maintenance)






