| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Chapter 9. The Service Registry</title><link rel="stylesheet" href="css/html.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="index.html" title="Eclipse Gemini Blueprint Reference Guide"><link rel="up" href="reference.html" title="Part II. Reference Documentation"><link rel="prev" href="app-deploy.html" title="Chapter 8. Packaging and Deploying Spring-based OSGi applications"><link rel="next" href="bundles.html" title="Chapter 10. Working With Bundles"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="service-registry"></a>Chapter 9. The Service Registry</h2></div></div></div><p>The OSGi service registry enables a bundle to publish objects to a |
| shared registry, advertised via a given set of Java interfaces. Published |
| services also have service properties associated with them in the |
| registry. The registry is a crucial feature of OSGi, facilitating decoupling |
| between bundles by promoting a dynamic collaborative model based on |
| a service-oriented paradigm (publish/find/bind).</p><p>Gemini Blueprint integrates tightly with the service registry, allowing |
| clients to publish, find and bind services in a POJO-friendly manner, without coupling |
| themselves to the OSGi API.</p><p>By using the <code class="literal">osgi</code> namespace for Spring (see |
| <a href="appendix-schema.html" title="Appendix F. Gemini Blueprint Schema">Appendix F, <i xmlns:xlink="http://www.w3.org/1999/xlink">Gemini Blueprint Schema</i></a>) one can be indicate what Spring beans to export |
| as OSGi services (and how) and to define the criteria and the manner in which |
| services available in the OSGi registry are imported as beans. |
| </p><p> |
| Just like the rest of the namespaces, the <code class="literal">osgi</code> namespace can be embedded |
| or nested inside another top-level namespace (typically the Spring <code class="literal">beans</code> |
| namespace) or be made the default namespace.</p><p>The following example shows the use of the <code class="literal">osgi</code> |
| namespace within the familiar Spring beans element:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:osgi</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans.xsd</span> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span><span class="hl-value"> |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd"</span>> |
| |
| <<span class="hl-tag">osgi:service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"simpleServiceOsgi"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"simpleService"</span> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.xyz.MyService"</span> /> |
| <<span class="hl-tag">/beans</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Use Spring Framework <code class="literal">beans</code> schema as the default namespace. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Import Gemini Blueprint schema and associate a prefix with its namespace (<code class="literal">osgi</code> in this example). |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Make sure to import Spring beans schema version <span class="emphasis"><em>3.0</em></span> or higher.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Use Gemini Blueprint elements using the declared namespace prefix (in this example <code class="literal">osgi</code>).</p></td></tr></table></div></div><p>Spring DM users can still use its namespace which is still supported by the Gemini Blueprint bundles. So the above configuration becomes:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:osgi</span>=<span class="hl-value">"http://www.springframework.org/schema/osgi"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans.xsd</span> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span><span class="hl-value"> |
| http://www.springframework.org/schema/osgi |
| http://www.springframework.org/schema/osgi/spring-osgi.xsd"</span>> |
| |
| <<span class="hl-tag">osgi:service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"simpleServiceOsgi"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"simpleService"</span> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.xyz.MyService"</span> /> |
| <<span class="hl-tag">/beans</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Use Spring Framework <code class="literal">beans</code> schema as the default namespace. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Import Gemini Blueprint schema and associate a prefix with its namespace (<code class="literal">osgi</code> in this example). |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Make sure to import Spring beans schema version <span class="emphasis"><em>3.0</em></span>.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Use Gemini Blueprint elements using the declared namespace prefix (in this example <code class="literal">osgi</code>).</p></td></tr></table></div></div><p>Through-out this documentation both the Gemini Blueprint and Spring DM namespaces will be used interchangeably - in fact, at a close look one will notice the two are identical (except for the |
| schema location declaration). As much as possible, new apps should use the Gemini Blueprint namespace as the Spring DM ones while supported, are being deprecated.</p><p>Using the OSGi namespace as a top-level namespace, the same service |
| would be declared as follows:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">?xml version="1.0" encoding="UTF-8"?</span>> |
| <<span class="hl-tag">beans:beans</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:beans</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <span class="hl-attribute">xsi:schemaLocation</span>=<span class="hl-value">"http://www.eclipse.org/gemini/blueprint/schema/blueprint |
| http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd |
| http://www.springframework.org/schema/beans |
| http://www.springframework.org/schema/beans/spring-beans.xsd"</span>> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| |
| <<span class="hl-tag">service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"simpleServiceOsgi"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"simpleService"</span> <span class="co"><img src="images/callouts/5.png" alt="(5)"></span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.xyz.MyService"</span> /> |
| |
| <<span class="hl-tag">/beans:beans</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| </pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p><code class="literal">beans</code> root element has to be prefixed with Spring Framework beans schema prefix (<code class="literal">beans</code> in this example). |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Use Gemini Blueprint schema as the default namespace. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Import Spring Framework <code class="literal">beans</code> schema and associate a prefix with its namespace (<code class="literal">beans</code> in this example). |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Make sure to import Spring beans schema version <span class="emphasis"><em>2.5</em></span>.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p>Use Gemini Blueprint elements without any prefix.</p></td></tr></table></div></div><p>Using the OSGi namespace as a top-level namespace is particularly |
| convenient when following the configuration <a href="app-deploy.html#app-deploy:headers:xml:tip" title="Tip">recommendation</a> from the previous section, |
| to use a dedicated configuration file for all OSGi-related declarations.</p><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:export"></a>9.1. Exporting A Spring Bean As An OSGi Service</h2></div></div></div><p>The <code class="literal">service</code> element is used to define a bean |
| representing an exported OSGi service. There are no requirements for |
| the class or object being exported - practically any bean can be exported. |
| At a minimum you must specify the bean to be exported, and the |
| <span class="emphasis"><em>service interface</em></span> that the service advertises.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">The publication <span class="emphasis"><em>interface</em></span> is used by service consumers, to identify the service. A service instance must implement the interface |
| - specifying a non-implemented interface results in an error. The term <span class="emphasis"><em>interface</em></span> is used in an abstract form; in practice any Java |
| interface or class, implemented or extended by the service instance can be specified.</td></tr></table></div><p>For example, the declaration</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToPublish"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>/></pre><p>exports the bean with name <code class="literal">beanToPublish</code> with |
| interface <code class="literal">com.xyz.MessageService</code>. The published |
| service will have a service property with the name |
| <code class="literal">org.eclipse.gemini.blueprint.bean.name</code> set to the name of |
| the target bean being registered (<code class="literal">beanToPublish</code> in |
| this case).</p><p>As an alternative to exporting a named bean, the bean to be |
| exported to the service registry may be defined as an anonymous inner |
| bean of the service element. Typically the top-level namespace would be |
| the <code class="literal">beans</code> namespace when using this style:</p><pre class="programlisting"><<span class="hl-tag">osgi:service</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>> |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"SomeClass"</span>> |
| ... |
| <<span class="hl-tag">/bean</span>> |
| <<span class="hl-tag">/osgi:service</span>></pre><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:registration"></a>9.1.1. Using The Service Registration</h3></div></div></div><p>Each <code class="literal">service</code> declaration, provides control access to the exported service. |
| The declaration returns an element of type <code class="interfacename">org.osgi.framework.ServiceRegistration</code> which can be |
| used to read or even modify the properties published for the OSGi service. Since DM 2.X, the definition |
| has been aligned with the Blueprint spec and unregistration of the service is not possible any more (an exception is thrown |
| if the <code class="methodname">unregister</code> is called). Additionally, the returned service registration will track |
| the service being registered (if multiple registration occur, these will be reflected in the returned registration object). |
| See <a href="service-registry.html#service-registry:export-import-relationship" title="9.2.1.2. Relationship Between The Service Exporter And Service Importer">Section 9.2.1.2, “Relationship Between The Service Exporter And Service Importer”</a> for more information on when registration/unregistration of |
| exported services can occur.</p><p>To use the service registration, simply inject the service bean definition into the relevant class; the example below |
| shows one way of updating the service properties from Java: |
| </p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myServiceRegistration"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToPublish"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>/> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"propUpdater"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.ServicePropertiesUpdater"</span>> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceRegistration ref="</span><span class="hl-attribute">myServiceRegistration"/></span> |
| <span class="hl-attribute"></bean></span></pre><p>Where <code class="classname">ServicePropertiesUpdater</code> can have the following definition:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> ServicePropertiesUpdater <span class="hl-keyword">implements</span> BeanNameAware { |
| |
| <span class="hl-keyword">private</span> ServiceRegistration serviceRegistration; |
| <span class="hl-keyword">private</span> String beanName; |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setServiceRegistration(ServiceRegistration serviceRegistration) { |
| <span class="hl-keyword">this</span>.serviceRegistration = serviceRegistration; |
| } |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> setBeanName(String beanName) { |
| <span class="hl-keyword">this</span>.beanName = beanName; |
| } |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> update() { |
| ServiceReference reference = serviceRegistration.getReference(); |
| <span class="hl-comment">// get current properties</span> |
| Dictionary dictionary = OsgiServiceReferenceUtils.getServiceProperties(reference); |
| dictionary.put(<span class="hl-string">"last-update"</span>, <span class="hl-keyword">new</span> Date()); |
| dictionary.put(<span class="hl-string">"updated-by"</span>, beanName); |
| dictionary.put(<span class="hl-string">"user.name"</span>, System.getProperties().getProperty(<span class="hl-string">"java.version"</span>)); |
| <span class="hl-comment">// update properties</span> |
| serviceRegistration.setProperties(dictionary); |
| } |
| }</pre><p>Each time the update() method is called, the service properties are retrived, new ones are added and finally the service |
| registration updated.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:service-factory"></a>9.1.2. <code class="interfacename">org.osgi.framework.ServiceFactory</code> Support</h3></div></div></div><p>OSGi Service Platform Core Specification allows services not just to be registered directly, |
| but also to be created on demand, through the <code class="interfacename">org.osgi.framework.ServiceFactory</code> |
| interface (see section 5.6). Gemini Blueprint/Spring DM recognizes this OSGi interface and honours its contract, |
| by forwarding each new bundle request, to the backing bean implementing the aforementioned interface.</p><p> As an alternative to implementing the OSGi API, one can use the <code class="literal">bundle</code> scope, introduced |
| by Gemini Blueprint/Spring DM which offers a <span class="emphasis"><em>instance-per-bundle</em></span> contract (see <a href="bnd-app-ctx.html#bnd-app-ctx:bundle-scope" title="7.5. Bundle Scope">Section 7.5, “Bundle Scope”</a> |
| for more information). To declare a bean with <code class="literal">bundle</code> scope |
| simply use the <code class="literal">scope</code> attribute of the |
| <code class="literal">bean</code> element:</p><pre class="programlisting"><<span class="hl-tag">osgi:service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>/> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">scope</span>=<span class="hl-value">"bundle"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.MessageServiceImpl"</span>/></pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:intfs"></a>9.1.3. Controlling The Set Of Advertised Service Interfaces For |
| An Exported Service</h3></div></div></div><p>The OSGi Service Platform Core Specification defines the term |
| <span class="emphasis"><em>service interface</em></span> to represent the specification |
| of a service's public methods. Typically this will be a Java |
| interface, but the specification also supports registering service |
| objects under a class name, so the phrase <span class="emphasis"><em>service |
| interface</em></span> can be interpreted as referring to either an |
| interface or a class.</p><p>There are several options for specifying the service |
| interface(s) under which the exported service is registered. The |
| simplest mechanism, shown above, is to use the |
| <code class="literal">interface</code> attribute to specify a fully-qualified |
| interface name. To register a service under multiple interfaces the |
| nested <code class="literal">interfaces</code> element can be used in place of |
| the <code class="literal">interface</code> attribute.</p><pre class="programlisting"><<span class="hl-tag">osgi:service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span>> |
| <<span class="hl-tag">osgi:interfaces</span>> |
| <<span class="hl-tag">value</span>>com.xyz.MessageService<<span class="hl-tag">/value</span>> |
| <<span class="hl-tag">value</span>>com.xyz.MarkerInterface<<span class="hl-tag">/value</span>> |
| <<span class="hl-tag">/osgi:interfaces</span>> |
| <<span class="hl-tag">/osgi:service</span>></pre><p>It is illegal to use both <code class="literal">interface</code> attribute and |
| <code class="literal">interfaces</code> element at the same time - use only one of them. |
| </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:export:auto-export"></a>9.1.3.1. Detecting The Advertised Interfaces At Runtime</h4></div></div></div><div class="sidebar"><p class="title"><b>Hierarchy visibility</b></p><p>Note that when using <code class="literal">auto-export</code>, only types visible to the |
| bundle exporting the service are registered. For example, a |
| super-interface <code class="literal">SI</code> would not be exported as a |
| supported service interface even when using |
| <code class="literal">auto-export="interfaces"</code> if <code class="literal">SI</code> |
| was not on the exporting bundle's classpath.</p><p>Even if exported service class does implement <code class="literal">SI</code> transitively based |
| on its parent, if the declaring bundle doesn't import the |
| interface, the class is unknown to the exported service. While this |
| might seem counter intuitive, it is actually one of the most powerful features of OSGi |
| which give the bundle authors control over the class visibility and path. |
| </p><p>Please see the FAQ for a more detailed explanation.</p></div><p>Using the <code class="literal">auto-export</code> attribute you can avoid |
| the need to explicitly declare the service interfaces at all by analyzing the |
| object class hierarchy and its interfaces.</p><p> |
| The <code class="literal">auto-export</code> attribute can have one of four |
| values:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="literal">disabled</code> : the default value; no auto-detected of service |
| interfaces is undertaken and the <code class="literal">interface</code> |
| attribute or <code class="literal">interfaces</code> element must be used |
| instead.</p></li><li><p><code class="literal">interfaces</code> : the service will be registered using all of the |
| Java interface types implemented by the bean to be exported</p></li><li><p><code class="literal">class-hierarchy</code> : the service will be registered using the |
| exported bean's implementation type and super-types</p></li><li><p><code class="literal">all-classes</code> : the service will be registered using the exported |
| bean's implementation type and super-types plus all interfaces |
| implemented by the bean.</p></li></ul></div><p> |
| <code class="literal">auto-export</code> and <code class="literal">interface(s)</code> option are not exclusive; both |
| can be used at the same time for fine grained control over the advertised interfaces if there is such |
| a need. However, the former option should be enough for most cases. |
| </p><p>For example, to automatically register a bean under all of the |
| interfaces that it supports you would declare:</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">auto-export</span>=<span class="hl-value">"interfaces"</span>/></pre><p>Given the interface hierarchy:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> SuperInterface {} |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> SubInterface <span class="hl-keyword">extends</span> SuperInterface {}</pre><p>then a service registered as supporting the |
| <code class="literal">SubInterface</code> interface is <span class="emphasis"><em>not</em></span> |
| considered a match in OSGi when a lookup is done for services |
| supporting the <code class="literal">SuperInterface</code> interface. For this |
| reason it is a best practice to export all interfaces supported by the |
| service being registered explicitly, using either the |
| <code class="literal">interfaces</code> element or |
| <code class="literal">auto-export="interfaces"</code>.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:props"></a>9.1.4. Controlling The Set Of Advertised Properties For An |
| Exported Service</h3></div></div></div><p>As previously described, an exported service is always |
| registered with the service property |
| <code class="literal">org.eclipse.gemini.blueprint.bean.name</code> set to the name |
| of the bean being exported. Since DM 2.x, the bean name is also published |
| under <code class="literal">osgi.service.blueprint.compname</code> (introduced by |
| the OSGi 4.2 Blueprint spec). |
| Additional service properties can be |
| specified using the nested <code class="literal">service-properties</code> |
| element. The <code class="literal">service-properties</code> element contains |
| key-value pairs to be included in the advertised properties of the |
| service. The key must be a string value, and the value must be a type |
| recognized by OSGi Filters. See section 5.5 of the OSGi Service |
| Platform Core Specification for details of how property values are |
| matched against filter expressions.</p><p>The <code class="literal">service-properties</code> element must contain |
| at least one nested <code class="literal">entry</code> element from the Spring |
| beans namespace. For example:</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyServiceInterface"</span>> |
| <<span class="hl-tag">service-properties</span>> |
| <<span class="hl-tag">beans:entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"myOtherKey"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"aStringValue"</span>/> |
| <<span class="hl-tag">beans:entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"aThirdKey"</span> <span class="hl-attribute">value-ref</span>=<span class="hl-value">"beanToExposeAsProperty"</span>/> |
| <<span class="hl-tag">/service-properties</span>> |
| <<span class="hl-tag">/service</span>></pre><p>Non-String values can be specified by enforcing the value type. Consider the publication |
| of an OSGi event consumer (<code class="interfacename">org.osgi.service.event.EventHandler</code>) |
| that needs to specify the topics it follows as an array under <code class="literal">event.topics</code> |
| property. Below are a list of configuration on how this can be achieved:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">osgi:service</span> |
| <span class="hl-attribute">id</span>=<span class="hl-value">"eventMonitorService"</span> |
| <span class="hl-attribute">ref</span>=<span class="hl-value">"someBean"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.osgi.service.event.EventHandler"</span>> |
| <<span class="hl-tag">osgi:service-properties</span> <span class="hl-attribute">value-type</span>=<span class="hl-value">"java.lang.String[]"</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"event.topics"</span> <span class="hl-attribute">value</span>=<span class="hl-value">"eventQueue"</span>/> |
| <<span class="hl-tag">/osgi:service-properties</span>> |
| <<span class="hl-tag">/osgi:service</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"> |
| Specify an array type for <span class="emphasis"><em>all</em></span> the values declared inside the <code class="literal">service-properties</code> element. |
| </td></tr></table></div></div><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">osgi:service</span> |
| <span class="hl-attribute">id</span>=<span class="hl-value">"eventMonitorService"</span> |
| <span class="hl-attribute">ref</span>=<span class="hl-value">"someBean"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.osgi.service.event.EventHandler"</span>> |
| <<span class="hl-tag">osgi:service-properties</span>> |
| <<span class="hl-tag">entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"event.topics"</span>> |
| <<span class="hl-tag">value</span> <span class="hl-attribute">type</span>=<span class="hl-value">"java.lang.String[]"</span>>eventQueue<<span class="hl-tag">/value</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">/entry</span>> |
| <<span class="hl-tag">/osgi:service-properties</span>> |
| <<span class="hl-tag">/osgi:service</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"> |
| Indicate the value type just for this particular value. |
| </td></tr></table></div></div><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">osgi:service</span> |
| <span class="hl-attribute">id</span>=<span class="hl-value">"eventMonitorService"</span> |
| <span class="hl-attribute">ref</span>=<span class="hl-value">"someBean"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"org.osgi.service.event.EventHandler"</span>> |
| <<span class="hl-tag">osgi:service-properties</span>> |
| <<span class="hl-tag">entry</span> <span class="hl-attribute">key</span>=<span class="hl-value">"event.topics"</span>> |
| <<span class="hl-tag">array</span> <span class="hl-attribute">value-type</span>=<span class="hl-value">"java.lang.String"</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">value</span>>eventQueue<<span class="hl-tag">/value</span>> |
| <<span class="hl-tag">/array</span>> |
| <<span class="hl-tag">/entry</span>> |
| <<span class="hl-tag">/osgi:service-properties</span>> |
| <<span class="hl-tag">/osgi:service</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"> |
| Use Spring 3.x <code class="literal"><array></code> element to create an nested array on the fly. |
| </td></tr></table></div></div><p>The Gemini Blueprint roadmap includes support for |
| exporting properties registered in the OSGi Configuration |
| Administration service as properties of the registered service. See |
| <a href="appendix-roadmap.html" title="Appendix D. Roadmap">Appendix D, <i xmlns:xlink="http://www.w3.org/1999/xlink">Roadmap</i></a> for more details.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:depends-on"></a>9.1.5. The depends-on Attribute</h3></div></div></div><p>Spring will manage explicit dependencies of a service element, |
| ensuring for example that the bean to be exported as a service is |
| fully constructed and configured before exporting it. If a service has |
| implicit dependencies on other components (including other service |
| elements) that must be fully initialized before the service can be |
| exported, then the optional <code class="literal">depends-on</code> attribute |
| can be used to express these dependencies.</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyServiceInterface"</span> |
| <span class="hl-attribute">depends-on</span>=<span class="hl-value">"myOtherComponent"</span>/></pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:ccl"></a>9.1.6. The context-class-loader Attribute</h3></div></div></div><p>The OSGi Service Platform Core Specification (most current |
| version is 4.x at time of writing) does not specify what types and |
| resources are visible through the context class loader when an |
| operation is invoked on a service obtained via the service registry. |
| Since some services may use libraries that make certain assumptions |
| about the context class loader, Gemini Blueprint enables you to |
| explicitly control the context class loader during service execution. |
| This is achieved using the option |
| <code class="literal">context-class-loader</code> attribute of the service |
| element.</p><p>The permissible values for the |
| <code class="literal">context-class-loader</code> attribute are |
| <code class="literal">unmanaged</code> (the default) and |
| <code class="literal">service-provider</code>. When the |
| <code class="literal">service-provider</code> value is specified, Spring Dynamic |
| Modules ensures that the context class loader can see all of the |
| resources on the class path of the bundle exporting the service.</p><p class="remark"><i><span class="remark">When setting <code class="literal">context-class-loader</code> to <code class="literal">service-provider</code>, the service object will be proxied to |
| handle the class loader. If the service advertises any concrete class then CGLIB library is required .</span></i></p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:ranking"></a>9.1.7. The <code class="literal">ranking</code> Attribute</h3></div></div></div><p>When registering a service with the service registry, you may |
| optionally specify a service ranking (see section 5.2.5 of the OSGi |
| Service Platform Core Specification). When a bundle looks up a service |
| in the service registry, given two or more matching services the one |
| with the highest ranking will be returned. The default ranking value |
| is zero. To explicitly specify a ranking value for the registered |
| service, use the optional <code class="literal">ranking</code> attribute.</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyServiceInterface"</span> |
| <span class="hl-attribute">ranking</span>=<span class="hl-value">"9"</span>/></pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:cache"></a>9.1.8. The <code class="literal">cache-target</code> Attribute</h3></div></div></div><p>By default, services exported are being retrieved from the container each time they are requested. |
| This allows <span class="emphasis"><em>scoped</em></span> beans to behave correctly depending on the context available |
| when the request is being performed. However, there are cases when the target bean (the entity being |
| exported) needs to be cached no matter its scope. The Blueprint spec for example requires this behaviour |
| for all exported services.</p><p>To accommodate both cases one, Gemini Blueprint 1.0/Spring DM 2.0 introduces a new attribute, <code class="literal">cache-target</code> |
| which, as the name suggests, enables the caching of the exported bean. The instance of the bean retrieved, |
| for the first service registration is cached internally by the exporter which will later reuse it.</p><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyServiceInterface"</span> |
| <span class="hl-attribute">cache-target</span>=<span class="hl-value">"true"</span>/></pre></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:service:attributes"></a>9.1.9. <code class="literal">service</code> Element Attributes</h3></div></div></div><p> |
| As a summary, the following table lists the attributes names, possible values and |
| a short description for each of them. |
| </p><div class="table"><a name="service-export-options"></a><p class="title"><b>Table 9.1. OSGi <service> attributes</b></p><div class="table-contents"><table summary="OSGi <service> attributes" width="100%" border="1"><colgroup><col><col><col><col><col><col align="center"></colgroup><thead><tr><th align="center">Name</th><th colspan="4" align="center">Values</th><th align="center">Description</th></tr></thead><tbody><tr><td align="center">interface</td><td colspan="4" align="center">fully qualified class name (such as <code class="classname">java.lang.Thread</code>)</td><td align="center">the fully qualified name of the class under which the object will be exported</td></tr><tr><td align="center">ref</td><td colspan="4" align="center">any bean name</td><td align="center">Reference to the named bean to be exported as a service in the service registry.</td></tr><tr><td align="center">context-class-loader</td><td colspan="2" align="center">unmanaged</td><td colspan="2" align="center">service-provider</td><td align="center">Defines how the context class loader will be managed when an operation is invoked on the |
| exported service. The default value is <code class="literal">unmanaged</code> which means that no management of |
| the context class loader is attempted. A value of <code class="literal">service-provider</code> guarantees that |
| the context class loader will have visibility of all the resources on the class path of |
| bundle exporting the service.</td></tr><tr><td align="center">auto-export</td><td align="center">disabled</td><td align="center">interfaces</td><td align="center">class-hierarchy</td><td align="center">all-classes</td><td align="center">Enables Spring to automatically manage the set of service interfaces advertised for the |
| service. By default this facility is <code class="literal">disabled</code>. A value of <code class="literal">interfaces</code> advertises all |
| of the Java interfaces supported by the exported service. A value of <code class="literal">class-hierarchy</code> |
| advertises all the Java classes in the hierarchy of the exported service. A value of |
| <code class="literal">all-classes</code> advertises all Java interfaces and classes.</td></tr><tr><td align="center">ranking</td><td colspan="4" align="center">any integer value</td><td align="center">Specify the service ranking to be used when advertising the service. Default value is 0.</td></tr><tr><td align="center">cache-target</td><td colspan="2" align="center">true</td><td colspan="2" align="center">false</td><td align="center">Specify whether the bean exported as an OSGi service is cached (on first registration) or not. Default value is <code class="literal">false</code></td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:export:lifecycle"></a>9.1.10. Service Registration And Unregistration Lifecycle</h3></div></div></div><p>The service defined by a <code class="literal">service</code> element is |
| registered with the OSGi service registry when the application context |
| is first created. It will be unregistered automatically when the |
| bundle is stopped and the application context is disposed. Additionally, |
| based on the mandatory service import availability, the service can be |
| unregistered and registered at runtime |
| (see ???).</p><p>If you need to take some action when a service is unregistered |
| because its dependencies are not satisfied (or when it is registered), |
| then you can define a listener bean using the nested |
| <code class="literal">registration-listener</code> element.</p><p>The declaration of a registration listener must use either the |
| <code class="literal">ref</code> attribute to refer to a top-level bean |
| definition, or declare an anonymous listener bean inline. For |
| example:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">service</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"beanToBeExported"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"SomeInterface"</span>> |
| <<span class="hl-tag">registration-listener</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"myListener"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">registration-method</span>=<span class="hl-value">"serviceRegistered"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">unregistration-method</span>=<span class="hl-value">"serviceUnregistered"</span>/> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <<span class="hl-tag">registration-listener</span> |
| <span class="hl-attribute">registration-method</span>=<span class="hl-value">"register"</span>> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"SomeListenerClass"</span>/> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <<span class="hl-tag">/registration-listener</span>> |
| <<span class="hl-tag">/service</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Listener declaration referring to a top-level bean declaration. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Indicate the <code class="literal">registration</code> and <code class="literal">unregistration</code> methods.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Declare only a <code class="literal">registration</code> custom method for this listener.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Nested listener bean declaration.</p></td></tr></table></div></div><p>The optional <code class="literal">registration-method</code> and |
| <code class="literal">unregistration-method</code> attributes specify the names |
| of the methods defined on the listener bean that are to be invoked |
| during registration and unregistration. A registration and unregistration |
| callback methods must have a signature matching one of the following formats:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(ServiceType serviceInstance, Map serviceProperties);</pre><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(ServiceType serviceInstance, Dictionary serviceProperties);</pre><p>where <code class="literal">ServiceType</code> can be any type compatible |
| with the exported service interface of the service.</p><p>The register callback is invoked when the service is initially |
| registered at startup, and whenever it is subsequently re-registered. |
| The unregister callback is invoked during the service unregistration process, |
| no matter the cause (such as the owning bundle stopping).</p><p>Gemini Blueprint/Spring DM will use the declared <code class="literal">ServiceType</code> argument type |
| and invoke the registration/unregistration method only when a service of a compatible type |
| will be registered/unregistered.</p><p><code class="literal">serviceProperties</code> represents a map holding all the properties |
| of the registered/unregistered service. To preserve compatibility with the OSGi specification |
| this argument can be cast, if needed, to a <code class="literal">java.util.Dictionary</code>.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:export:lifecycle:interface"></a>9.1.10.1. Using <code class="interfacename">OsgiServiceRegistrationListener</code> Interface</h4></div></div></div><p> |
| While we discourage, it is possible to implement a Gemini Blueprint/Spring DM specific interface, namely |
| <code class="interfacename">org.eclipse.gemini.blueprint.service.exporter.OsgiServiceRegistrationListener</code> which avoids the need |
| to declare the <code class="literal">registration-method</code> and <code class="literal">unregistration-method</code>. |
| However, by implementing <code class="interfacename">OsgiServiceRegistrationListener</code>, your code |
| becomes Gemini Blueprint/Spring DM aware (which goes against the POJO philosophy). |
| </p><p>It is possible for a listener to implement <code class="interfacename">OsgiServiceRegistrationListener</code> interface and |
| declare custom methods. In this case, the Gemini Blueprint/Spring DM interface methods will be called first, followed by the custom methods. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:export:blueprint"></a>9.1.10.2. Blueprint <code class="literal">service</code> Comparison</h4></div></div></div><p>The Blueprint Container offers a <code class="literal">service</code> element, identical in functionality with the one in Gemini Blueprint/Spring DM. In most cases, |
| the configuration should be identical. Below is a summary of the configuration options available in Gemini Blueprint/Spring DM and Blueprint:</p><div class="table"><a name="service-registry:export:blueprint:comparison"></a><p class="title"><b>Table 9.2. Spring DM / Blueprint <code class="literal"><service></code> Configuration Comparison</b></p><div class="table-contents"><table summary="Spring DM / Blueprint <service> Configuration Comparison" width="100%" border="1"><colgroup><col><col></colgroup><thead><tr><th align="center">Gemini Blueprint/Spring DM</th><th align="center">Blueprint</th></tr></thead><tbody><tr><td align="center">interface</td><td align="center">interface</td></tr><tr><td align="center">ref</td><td align="center">ref</td></tr><tr><td align="center">auto-export</td><td align="center">auto-export</td></tr><tr><td align="center">ranking</td><td align="center">ranking</td></tr><tr><td align="center">context-class-loader</td><td align="center">-</td></tr><tr><td align="center">cache-target</td><td align="center">- (caching is always enabled)</td></tr></tbody></table></div></div><br class="table-break"><p>Since the <code class="literal">registration-listener</code> declaration is identical in declaration and functionality between Blueprint |
| and Gemini Blueprint/Spring DM, this section does not mention it.</p></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:refs"></a>9.2. Defining References To OSGi Services</h2></div></div></div><p>To use services, clients need to look for them inside the OSGi service registry. |
| If found, the platform returns a reference which can be used to get the actual service instance. |
| Consumers should return the service instance as soon as possible and not hold on to it since |
| the service provider can unpublish the service at any point. |
| Since there is no mechanism in Java to force such cleanup, the OSGi specification uses the service |
| references and the aforementioned <span class="emphasis"><em>protocol</em></span> to decouple service providers from |
| service consumers. Please see chapter 5, the Service Layer inside the OSGi Core spec for an in-depth |
| discussion. |
| </p><p>Gemini Blueprint facilitates the consumption of OSGi services by taking care of not |
| just of the retrieval of service references and instances but also considering the service dynamics. |
| With Gemini Blueprint/Spring DM, imported OSGi services become Spring beans which can be injected, as usual, |
| into other application components. The service lookup is made using the service interface type |
| that the service is required to support, plus an optional filter |
| expression that matches against the service properties published in the |
| registry. The service instance retrieval is done on demand, on the first request. Once the service |
| becomes unavailable, Gemini Blueprint/Spring DM automatically unregisters the service to avoid using <span class="emphasis"><em>stale</em></span> |
| references.</p><p>As a consumer, one can find zero, one or multiple services matching the desired description. |
| In most scenarios, a single matching service is all that is needed; for those the |
| <code class="literal">reference</code> element defines a reference to a single |
| service that meets the required specification. |
| In other cases, especially when using the OSGi <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.osgi.org/documents/osgi_technology/whiteboard.pdf" target="_top">whiteboard |
| pattern</a>, references to <span class="emphasis"><em>all available</em></span> |
| matching services are required. Gemini Blueprint supports the |
| management of this group of references as either a <code class="interfacename">List</code> or a |
| <code class="interfacename">Set</code> collection.</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:availability"></a>9.2.1. Imported Service Availability</h3></div></div></div><div class="sidebar"><p class="title"><b>What happened to <code class="literal">cardinality</code>?</b></p><p> |
| Since Spring DM 2.x/Gemini Blueprint, the <code class="literal">cardinality</code> notion has been deprecated in favour |
| of <code class="literal">availability</code>. The main reasons behind it were aligning the terminology |
| with the Blueprint spec and eliminating the repetition of specifying the number of imported |
| services: as <code class="literal">osgi</code> elements already specify whether one or multiple services |
| are imported, the <code class="literal">cardinality</code> right side (<code class="literal">..N/..1</code>) was |
| redundant. |
| </p></div><p>Due to the dynamic nature of OSGi, services can come and go, be available or unavailable |
| at certain points in time. Depending on the type of service, this can have a negative impact |
| on the consumers. Gemini Blueprint/Spring DM alleviates this problem by introducing the |
| notion of <code class="literal">availability</code> (formerly known as <code class="literal">cardinality</code>) |
| which indicates whether an imported service is <code class="literal">mandatory</code> or |
| <code class="literal">optional</code>.</p><p>As the name implies, a <code class="literal">mandatory</code> service implies a crucial application dependency: |
| the service is <span class="emphasis"><em>required</em></span> and its presence can heavily impact the application, in |
| a negative way. |
| </p><p>An <code class="literal">optional</code> service means just the opposite. The service is tracked and bound |
| (if present), just like a <code class="literal">mandatory</code> reference, but its presence is not required. It is |
| fine, from an application perspective if the service is not available - its existence (or lack of) does |
| not impact the application functionality.</p><p>As an example, an application could have a <code class="literal">mandatory</code> dependency on a <code class="literal"> |
| DataSource</code> and an <code class="literal">optional</code> one for a logging service: the application can run fine |
| if it cannot log (it does not impact the runtime) but it fails if the backing database is not available.</p><p>In Gemini Blueprint/Spring DM, a <code class="literal">mandatory</code> service import that is unsatisfied (there are no services |
| matching the description) can either prevent an application context from starting up or, if already started, |
| cause the unregistration of the exported services dependent on it.</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:availability:startup"></a>9.2.1.1. Mandatory Services and Application Startup</h4></div></div></div><p> |
| The availability of a service impacts the startup of an Spring-powered application and |
| the publication of any exported services that depend on it. |
| As mentioned in <a href="bnd-app-ctx.html#bnd-app-ctx:app-creation:mandatory-deps" title="7.2.1. Mandatory Service Dependencies">Section 7.2.1, “Mandatory Service Dependencies”</a>, a SpringDM application will not start |
| unless <span class="emphasis"><em>all</em></span> <code class="literal">mandatory</code> services are available, at the same time. |
| |
| Before initializing the context, Gemini Blueprint/Spring DM discovers all the <code class="literal">mandatory</code> service |
| declarations and waits for a period of time (5 minutes by default unless otherwise specified by |
| each bundle - see the <code class="literal">timeout</code> directive in <a href="app-deploy.html#app-deploy:headers" title="8.1. Bundle Format And Manifest Headers">Section 8.1, “Bundle Format And Manifest Headers”</a>) for all imports |
| to be satisfied, at the same time. |
| If the timeout occurs, the application initialization fails (since the required or mandatory services |
| are not available) or succeeds, meaning the application context is being initialized. |
| </p><p>This way, the framework prevents the application from starting up only to fail since its required |
| services are unavailable. This feature avoids the need for ordering the bundle startup sequence as the |
| configuration already acts as a service <span class="emphasis"><em>barrier</em></span> blueprint: no matter the order of the services |
| started, on whether they come and go, only when all of them are present, will the context initialization |
| commence.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">The fact that an application has mandatory service references, gives no guarantee |
| that a valid service object is available when the service reference is used, since services can |
| get unregistered at any time. Gemini Blueprint/Spring DM guarantees that all the mandatory services were present, at |
| the same time, before the application was started but it cannot prevent or guarantee that this services |
| will not be disappear during the application life span.</td></tr></table></div><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Warning"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="images/admons/warning.png"></td><th align="left">Warning</th></tr><tr><td align="left" valign="top"> |
| It is an error to declare a mandatory reference to a |
| service that is also exported by the same bundle, this behaviour can |
| cause application context creation to fail through either deadlock |
| or timeout. |
| </td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:export-import-relationship"></a>9.2.1.2. Relationship Between The Service Exporter And Service Importer</h4></div></div></div><p>An exported service may depend, either directly or indirectly, |
| on other (imported) services in order to perform its function. If one of these |
| services is marked as a <span class="emphasis"><em>mandatory</em></span> dependency and the |
| dependency can no longer be satisfied |
| (because the backing service has gone away and there is no suitable |
| replacement available), then the exported service that depends on it |
| will be automatically unregistered from the service registry - meaning |
| that it is no longer available to clients. If the mandatory dependency |
| becomes satisfied once more (by registration of a suitable service), |
| then the exported service will be re-registered in the service |
| registry.</p><p>This automatic publication management ensures that only when the exported service can work reliable, |
| it is made available for potential OSGi clients. This behaviour takes advantage of the OSGi dynamic nature |
| allowing an application to cope with the ongoing changing without being restarted. |
| </p><p>This automatic unregistering and re-registering of exported |
| services based on the availability of mandatory dependencies only |
| takes into account declarative dependencies. If exported service |
| <code class="literal">S</code> depends on bean <code class="literal">A</code>, which in |
| turn depends on mandatory imported service <code class="literal">M</code>, and |
| these dependencies are explicit in the Spring configuration file as |
| per the example below, then when <code class="literal">M</code> becomes |
| unsatisfied <code class="literal">S</code> will be unregistered. When |
| <code class="literal">M</code> becomes satisfied again, <code class="literal">S</code> |
| will be re-registered.</p><pre class="programlisting"><<span class="hl-tag">osgi:service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"S"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"A"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"SomeInterface"</span>/> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"A"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"SomeImplementation"</span>> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"helperService"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"M"</span>/> |
| <<span class="hl-tag">/bean</span>> |
| |
| <<span class="hl-comment">!-- the reference element is used to refer to a service |
| in the service registry --</span>> |
| <<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"M"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"HelperService"</span> <span class="hl-attribute">availability</span>=<span class="hl-value">"mandatory"</span>/></pre><p>If however the dependency from <code class="literal">A</code> on |
| <code class="literal">M</code> is not established through configuration as shown |
| above, but instead at runtime through for example passing a reference |
| to <code class="literal">M</code> to <code class="literal">A</code> without any |
| involvement from the Spring container, then Gemini Blueprint |
| will <span class="emphasis"><em>not</em></span> track this dependency.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:singular"></a>9.2.2. Referencing An Individual Service</h3></div></div></div><p>The <code class="literal">reference</code> element is used to define a |
| reference to a service in the service registry.</p><p>Since there can be multiple service matching a given description, |
| the service returned is the service that would be returned by a call to |
| <code class="literal">BundleContext.getServiceReference</code>. This means that |
| the service with the highest ranking will be returned, or if there is |
| a tie in ranking, the service with the lowest service id (the service |
| registered first with the framework) is returned (please see Section 5 |
| from the OSGi spec for more information on the service selection algorithm).</p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:interface"></a>9.2.2.1. Controlling The Set Of Advertised Interfaces For The Imported Service</h4></div></div></div><p>The <code class="literal">interface</code> attribute identifies the service |
| interface that a matching service must implement. For example, the |
| following declaration creates a bean |
| <code class="literal">messageService</code>, which is backed by the service |
| returned from the service registry when querying it for a service |
| offering the <code class="interfacename">MessageService</code> interface.</p><pre class="programlisting"><<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>/></pre><p>Just like the <code class="literal">service</code> declaration, when specifying |
| multiple interfaces, use the nested <code class="literal">interfaces</code> element instead |
| of <code class="literal">interface</code> attribute: |
| </p><pre class="programlisting"><<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"importedOsgiService"</span>> |
| <<span class="hl-tag">osgi:interfaces</span>> |
| <<span class="hl-tag">value</span>>com.xyz.MessageService<<span class="hl-tag">/value</span>> |
| <<span class="hl-tag">value</span>>com.xyz.MarkerInterface<<span class="hl-tag">/value</span>> |
| <<span class="hl-tag">/osgi:interfaces</span>> |
| <<span class="hl-tag">/osgi:reference</span>></pre><p>It is illegal to use both <code class="literal">interface</code> attribute and |
| <code class="literal">interfaces</code> element at the same time - use only one of them. |
| </p><p>The bean defined by reference element implements all of the |
| advertised interfaces of the service that are visible to the bundle (called |
| <span class="emphasis"><em>greedy proxying</em></span>). |
| If the registered service interfaces include Java class types (as |
| opposed to interface types) then support for these types is subject to |
| the restrictions of Spring's AOP implementation (see the Spring |
| Reference Guide). In short, if the specified interfaces are classes |
| (rather then interfaces), then <code class="literal">cglib</code> library must be |
| available, and <code class="literal">final</code> methods are not |
| supported.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:filter"></a>9.2.2.2. The <code class="literal">filter</code> Attribute</h4></div></div></div><p>The optional <code class="literal">filter</code> attribute can be used |
| to specify an OSGi filter expression and constrains the service |
| registry lookup to only those services that match the given |
| filter.</p><p>For example:</p><pre class="programlisting"><<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"asyncMessageService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span> |
| <span class="hl-attribute">filter</span>=<span class="hl-value">"(asynchronous-delivery=true)"</span>/></pre><p>will match only OSGi services that advertise <code class="interfacename">MessageService</code> |
| interface and have the property named <code class="literal">asynchronous-delivery</code> set to value <code class="literal">true</code>. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:bean-name"></a>9.2.2.3. The <code class="literal">bean-name</code> Attribute</h4></div></div></div><p>The <code class="literal">bean-name</code> attribute is a convenient |
| short-cut for specifying a filter expression that matches on the |
| <code class="literal">bean-name</code> property automatically set when exporting a bean using the |
| <code class="literal">service</code> element (see <a href="service-registry.html#service-registry:export" title="9.1. Exporting A Spring Bean As An OSGi Service">Section 9.1, “Exporting A Spring Bean As An OSGi Service”</a>).</p><p>Consider the following exporter/importer declarations:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"</span><span class="co"><img src="images/callouts/1.png" alt="(1)"></span><span class="hl-value">messageServiceBean"</span> <span class="hl-attribute">scope</span>=<span class="hl-value">"bundle"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"com.xyz.MessageServiceImpl"</span>/> |
| <<span class="hl-comment">!-- service exporter --</span>> |
| <<span class="hl-tag">osgi:service</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageServiceExporter"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"</span><span class="co"><img src="images/callouts/1.png" alt="(1)"></span><span class="hl-value">messageServiceBean"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>/> |
| </pre></div><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"messageService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span> |
| <span class="hl-attribute">bean-name</span>=<span class="hl-value">"</span><span class="co"><img src="images/callouts/1.png" alt="(1)"></span><span class="hl-value">messageServiceBean"</span>/> |
| </pre></div><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>the name used with <code class="literal">bean-name</code> attribute</p></td></tr></table></div><p>will match only OSGi services that advertise <code class="interfacename">MessageService</code> |
| interface and have the property named <code class="literal">org.eclipse.gemini.blueprint.bean.name</code> set |
| to value <code class="literal">messageServiceBean</code>. In short, this means finding all Gemini Blueprint/Spring DM exported |
| beans that implement interface <code class="interfacename">MessageService</code> and are named |
| <code class="literal">messageServiceBean</code>.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:cardinality"></a>9.2.2.4. The <code class="literal">availability</code> Attribute</h4></div></div></div><div class="sidebar"><p class="title"><b>Nested <reference> declarations</b></p><p>In order for Gemini Blueprint/Spring DM to detect mandatory dependencies, any |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-inner-beans" target="_top">nested/inner</a> |
| reference declaration will be transformed into top-level |
| one with a generated name.</p></div><p>The <code class="literal">availability</code> attribute is used to |
| specify whether or not a matching service is required at all times. |
| An <code class="literal">mandatory</code> availability (the default) |
| indicates that a matching service must always be present. A |
| value of <code class="literal">optional</code> indicates that a |
| matching service is not required at all times (see |
| <a href="service-registry.html#service-registry:refs:singular:dynamics" title="9.2.2.9. reference And OSGi Service Dynamics">Section 9.2.2.9, “<code class="literal">reference</code> And OSGi Service Dynamics”</a> |
| for more details). The differences in behaviour between <code class="literal">mandatory</code> |
| and <code class="literal">optional</code> services are explained at length in |
| <a href="service-registry.html#service-registry:refs:availability" title="9.2.1. Imported Service Availability">Section 9.2.1, “Imported Service Availability”</a>. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:depends-on"></a>9.2.2.5. The <code class="literal">depends-on</code> Attribute</h4></div></div></div><p>The <code class="literal">depends-on</code> attribute is used to specify |
| that the service reference should not be looked up in the service |
| registry until the named dependent bean has been |
| instantiated.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:tccl"></a>9.2.2.6. The <code class="literal">context-class-loader</code> Attribute</h4></div></div></div><p>The OSGi Service Platform Core Specification (latest |
| version is 4.1 at time of writing) does not specify what types and |
| resources are visible through the context class loader when an |
| operation is invoked on a service obtained via the service registry. |
| Since some services may use libraries that make certain assumptions |
| about the context class loader, Gemini Blueprint enables you |
| to explicitly control the context class loader during service |
| invocation. This is achieved using the option |
| <code class="literal">context-class-loader</code> attribute of the |
| <code class="literal">reference</code> element.</p><div class="sidebar"><p class="title"><b>context class loader management on the importer and exporter</b></p><p> |
| Gemini Blueprint/Spring DM has the ability to do context class loader management on both |
| the importer and exporter side. Normally, if Gemini Blueprint/Spring DM works on both sides, |
| only one side should have this feature enabled. However, if both sides |
| (importer and exporter) take advantage of this capability, the last |
| entity in the call chain will win. This means that the exporter setting, |
| if enabled, will always override the importer setting (whatever that is). |
| </p></div><p>The permissible values for the |
| <code class="literal">context-class-loader</code> attribute are:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="literal">client</code> - during the service invocation, |
| the context class loader is guaranteed to be |
| able to see types on the classpath of the invoking bundle. |
| This is the default option.</p></li><li><p><code class="literal">service-provider</code> - during the service invocation, |
| the context class loader is guaranteed to be |
| able to see types on the classpath of the bundle exporting |
| the service.</p></li><li><p><code class="literal">unmanaged</code> - no context class loader |
| management will occur during the service invocation</p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:sticky"></a>9.2.2.7. The <code class="literal">sticky</code> Attribute</h4></div></div></div><p>Newly introduced in DM 2.x, the <code class="literal">sticky</code> attribute specifies whether an importer will use |
| a backing service until it becomes unavailable or whether it will consider other <span class="emphasis"><em>better</em></span> candidates |
| (defined as services matching the importer criteria but with a higher ranking or a lower service id) that might appear. |
| In Spring DM 1.x, the importer would always select the best service available at any point in time. Thus, if a service with |
| a higher ranking id becomes available, the proxy would automatically bind to it. In highly dynamic environments, this lack |
| of service affinity becomes problematic so in DM 2.x/Gemini Blueprint, the behaviour has changed (aligning itself with the Blueprint spec). |
| Thus, service importers become <code class="literal">sticky</code> by default meaning that a proxy will use the bound backing service |
| until it becomes unavailable, ignoring any other service updates. Only when the backing service goes down, the proxy will |
| look for a replacement selecting the best candidate at that point in time. |
| To revert to the Spring DM 1.x behaviour, mark the importers as being non-sticky.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:reference:attributes"></a>9.2.2.8. <code class="literal">reference</code> Element Attributes</h4></div></div></div><p> |
| As a summary, the following table lists the <code class="literal">reference</code> element |
| attributes names, possible values and a short description for each of them. |
| </p><div class="table"><a name="reference-import-options"></a><p class="title"><b>Table 9.3. OSGi <reference> attributes</b></p><div class="table-contents"><table summary="OSGi <reference> attributes" width="100%" border="1"><colgroup><col><col align="center"><col align="center"><col align="center"><col align="center"></colgroup><thead><tr><th>Name</th><th colspan="4" align="center">Values</th><th align="justify">Description</th></tr></thead><tbody><tr><td>interface</td><td colspan="4" align="center">fully qualified class name (such as <code class="classname">java.lang.Thread</code>)</td><td align="justify">The fully qualified name of the class under which the object will be exported.</td></tr><tr><td>filter</td><td colspan="4" align="center">OSGi filter expression (such as <code class="literal">((asynchronous-delivery=true)</code>)</td><td align="justify">OSGi filter expression that is used to constrain the set of matching services |
| in the service registry.</td></tr><tr><td>bean-name</td><td colspan="4" align="center">any string value</td><td align="justify">Convenient shortcut for specifying a filter expression that matches on the bean-name property |
| that is automatically advertised for beans published using the <service> element.</td></tr><tr><td>context-class-loader</td><td align="center">client</td><td colspan="2" align="center">service-provider</td><td align="center">unmanaged</td><td align="justify">Defines how the context class loader is managed when invoking operations on a service |
| backing this service reference. The default value is <code class="literal">client</code> which means that the context |
| class loader has visibility of the resources on this bundle's classpath. Alternate |
| options are <code class="literal">service-provider</code> which means that the context class loader has visibility of |
| resources on the bundle classpath of the bundle that exported the service, and <code class="literal">unmanaged</code> |
| which does not do any management of the context class loader.</td></tr><tr><td>availability</td><td colspan="2" align="center">optional</td><td colspan="2" align="center">mandatory</td><td align="justify">Defines the desired availability of the relationship to the backing service. If not specified, |
| the <code class="literal">default-availability</code> attribute will apply. 'mandatory' value (the default) means that a backing service |
| must exist at all times. The 'optional' value indicates that it is acceptable to be for an importer to have no |
| backing service.</td></tr><tr><td>timeout</td><td colspan="4" align="center">any positive long</td><td align="justify">The amount of time (in milliseconds) to wait for a backing service to be |
| available when an operation is invoked. If not specified, the <code class="literal">default-timeout</code> attribute will apply. |
| </td></tr><tr><td>sticky</td><td colspan="2" align="center">true</td><td colspan="2" align="center">false</td><td align="justify">Indicates the <span class="emphasis"><em>stickiness</em></span> of the service import. If 'true' (default), the proxy will rebind only if the |
| backing service is no longer available. If 'false' (Spring DM 1.x behaviour), the rebind will occur every time a 'better' candidate |
| appears. A better service is defined by having either a higher ranking or the same ranking and a lower service id. |
| </td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:dynamics"></a>9.2.2.9. <code class="literal">reference</code> And OSGi Service Dynamics</h4></div></div></div><p> |
| The bean defined by the <code class="literal">reference</code> element |
| is unchanged throughout the lifetime of the application context |
| (the object reference remains constant). However, the OSGi service |
| that backs the reference may come and go at any time. For a |
| mandatory service reference, the creation of the application context will block until a matching |
| service is available. <a href="service-registry.html#service-registry:refs:availability" title="9.2.1. Imported Service Availability">Section 9.2.1, “Imported Service Availability”</a> provides |
| more details.</p><p>When the service backing a <code class="literal">reference</code> bean |
| goes away, Gemini Blueprint tries to replace the backing |
| service with another service matching the reference criteria. An |
| application may be notified of a change in backing service by |
| registering a <code class="literal">reference-listener</code>. If no matching service is |
| available, then the <code class="literal">reference</code> is said to be |
| <span class="emphasis"><em>unsatisfied</em></span>. An unsatisfied mandatory service |
| causes any exported service (<code class="literal">service</code> bean) that |
| depends on it to be unregistered from the service registry until |
| such time as the reference is satisfied again. See |
| <a href="service-registry.html#service-registry:export-import-relationship" title="9.2.1.2. Relationship Between The Service Exporter And Service Importer">Section 9.2.1.2, “Relationship Between The Service Exporter And Service Importer”</a> for more information.</p><p>When an operation is invoked on an unsatisfied |
| <code class="literal">reference</code> bean (either optional or mandatory), |
| the invocation blocks until the reference becomes satisfied. The |
| optional <code class="literal">timeout</code> attribute of the |
| <code class="literal">reference</code> element enables a timeout value (in |
| milliseconds) to be specified. If no matching service becomes available |
| within the timeout period, an unchecked <code class="classname">ServiceUnavailableException</code> is |
| thrown.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:singular:property-editor"></a>9.2.2.10. Getting A Hold Of The Managed Service Reference</h4></div></div></div><p>Gemini Blueprint/Spring DM can automatically convert a managed OSGi service to |
| service reference. That is, if the property into which a reference bean |
| is to be injected, has type <code class="interfacename">ServiceReference</code> (instead of the service |
| interface supported by the reference), then the managed OSGi |
| <code class="interfacename">ServiceReference</code> for the service will be injected |
| in place of the service itself:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> BeanWithServiceReference { |
| <span class="hl-keyword">private</span> ServiceReference serviceReference; |
| <span class="hl-keyword">private</span> SomeService service; |
| |
| <span class="hl-comment">// getters/setters ommitted</span> |
| }</pre><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.SomeService"</span>/> |
| |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someBean"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"BeanWithServiceReference"</span>> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"serviceReference"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"service"</span>/> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"service"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"service"</span>/> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <<span class="hl-tag">/bean</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Automatic managed service to <code class="interfacename">ServiceReference</code> conversion. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Managed service is injected without any conversion</p></td></tr></table></div></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"> |
| The injected <code class="interfacename">ServiceReference</code> is managed by Gemini Blueprint/Spring DM and will change |
| at the same time as the referenced backing OSGi service instance. |
| </td></tr></table></div><p>There are cases when the managed <code class="interfacename">ServiceReference</code> is needed to get a hold of the OSGi service. Unfortunately, |
| most of the OSGi frameworks expect their own <code class="interfacename">ServiceReference</code> classes and will fail when the |
| Gemini Blueprint/Spring DM managed reference is used. For such cases, one can get a hold of the native <code class="interfacename">ServiceReference</code> bound |
| at that moment, by casting the reference object to <code class="interfacename">ServiceReferenceProxy</code> and then calling |
| <code class="methodname">getTargetServiceReference</code>. Using the example context above, one might use the following code:</p><pre class="programlisting">ServiceReference nativeReference = ((ServiceReferenceProxy)serviceReference).getTargetServiceReference()</pre><p>The returned <code class="literal">nativeReference</code> can be safely passed to the OSGi framework however, since it is not managed by Gemini Blueprint/Spring DM, |
| in time, it might refer to a service different then the one backing the imported OSGi service.</p><p>To avoid this desynchronization, consider using managed <code class="interfacename">ServiceReference</code> objects mainly for reading the |
| bound OSGi service properties rather then getting a hold of OSGi services (which can be simply injected by Gemini Blueprint/Spring DM).</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:collection"></a>9.2.3. Referencing A Collection Of Services</h3></div></div></div><div class="sidebar"><p class="title"><b>Natural vs custom ordering</b></p><p> |
| Java collection API defines two interfaces for ordering objects - |
| <code class="interfacename">Comparable</code> and <span class="interface">Comparator</span>. |
| The first is meant to be implemented by objects for providing <span class="emphasis"><em>natural |
| ordering</em></span>. <code class="classname">String</code>, <code class="classname">Long</code> |
| or <code class="classname">Date</code> are good examples of objects that implement the |
| <code class="interfacename">Comparable</code> interface.</p><p> |
| However, there are cases where sorting is different then the natural ordering or, |
| the objects meant to be sort do not implement <span class="interface">Comparable</span>. To |
| address this cases, <code class="interfacename">Comparator</code> interface was designed. |
| </p><p>For more information on this subject, please consult the <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://java.sun.com/docs/books/tutorial/collections/interfaces/order.html" target="_top"> |
| Object ordering</a> chapter from Java |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://java.sun.com/docs/books/tutorial/collections/" target="_top">collection</a> tutorial, |
| </p></div><p>Sometimes an application needs access not simply to any service |
| meeting some criteria, but to <span class="emphasis"><em>all</em></span> services |
| meeting some criteria. Gemini Blueprint/Spring DM allows the matching services may be held in a |
| <code class="interfacename">List</code> or <code class="interfacename">Set</code> |
| (optionally sorted).</p><p>The difference between using a <code class="interfacename">List</code> and a |
| <code class="interfacename">Set</code> to manage the collection is one of equality. |
| Two or more services published in the registry (and with distinct |
| service ids) may be "equal" to each other, depending on the |
| implementation of equals used by the service implementations. Only one |
| such service will be present in a set, whereas all services returned |
| from the registry will be present in a list. For more details on collections, |
| see <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html" target="_top">this</a> |
| tutorial.</p><p>The <code class="literal">set</code> and <code class="literal">list</code> schema elements |
| are used to define collections of services with set or list semantics |
| respectively.</p><p>These elements support the attributes |
| <code class="literal">interface</code>, <code class="literal">filter</code>, |
| <code class="literal">bean-name</code>, <code class="literal">availability</code>, and |
| <code class="literal">context-class-loader</code>, with the same semantics as for |
| the <code class="literal">reference</code> element. The allowable values for the |
| <code class="literal">availability</code> attribute are <code class="literal">mandatory</code> |
| and <code class="literal">optional</code>.</p><p>An availability value of |
| <code class="literal">optional</code> indicates that it is permissible to |
| be no matching services. An availability value of |
| <code class="literal">mandatory</code> indicates that at least one matching service |
| is required at all times. Such a reference is considered a |
| <span class="emphasis"><em>required</em></span> reference and any exported services |
| from the same bundle (<code class="literal">service</code> defined beans) that |
| depend on a mandatory reference will automatically be unregistered |
| when the reference becomes unsatisfied, and reregistered when the |
| reference becomes satisfied again. See <a href="service-registry.html#service-registry:refs:availability" title="9.2.1. Imported Service Availability">Section 9.2.1, “Imported Service Availability”</a> |
| for more details.</p><p>The bean defined by a <code class="literal">list</code> element is of type |
| <code class="interfacename">java.util.List</code>. The bean defined by a |
| <code class="literal">set</code> element is of type |
| <code class="interfacename">java.util.Set</code>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">Make sure the Gemini Blueprint/Spring DM collections are injected into properties of compatible types ( |
| for example <code class="literal">set</code> into <code class="interfacename">Set</code> or <code class="interfacename"> |
| Collection</code>) since otherwise the container will automatically perform |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://static.springframework.org/spring/docs/2.5.x/reference/validation.html#beans-beans-conversion" target="_top">type conversion</a>, |
| transforming the Gemini Blueprint/Spring DM managed collection into a 'normal' one, unaware of the OSGi dynamics. |
| </td></tr></table></div><p>The following example defines a bean of type <code class="interfacename">List</code> that |
| will contain all registered services supporting the |
| <code class="literal">EventListener</code> interface:</p><pre class="programlisting"><<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myEventListeners"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.EventListener"</span>/></pre><p>The members of the collection defined by the bean are managed |
| dynamically by Spring. As matching services are registered and |
| unregistered in the service registry, the collection membership will |
| be kept up to date. Each member of the collection supports the service |
| interfaces that the corresponding service was registered with and that |
| are visible to the bundle.</p><p>Gemini Blueprint/Spring DM supports sorted collections as well, both for set and list.</p><p>It is possible to specify a sorting order using either the |
| <code class="literal">comparator-ref</code> attribute, or the nested |
| <code class="literal">comparator</code> element. The |
| <code class="literal">comparator-ref</code> attribute is used to refer to a |
| named bean implementing <code class="interfacename">java.util.Comparator</code>. The |
| <code class="literal">comparator</code> element can be used to define an inline |
| bean. For example:</p><pre class="programlisting"><<span class="hl-tag">set</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myServices"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyService"</span> |
| <span class="hl-attribute">comparator-ref</span>=<span class="hl-value">"someComparator"</span>/> |
| |
| <<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myOtherServices"</span> |
| <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.OtherService"</span>> |
| <<span class="hl-tag">comparator</span>> |
| <<span class="hl-tag">beans:bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"MyOtherServiceComparator"</span>/> |
| <<span class="hl-tag">/comparator</span>> |
| <<span class="hl-tag">/list</span>></pre><p>To sort using a natural ordering instead of an explicit |
| comparator, you can use the <code class="literal">natural</code> |
| element inside of <code class="literal">comparator</code>. You need to specify |
| the basis for the natural ordering: based on the service references, |
| following the <code class="interfacename">ServiceReference</code> natural ordering |
| defined in the OSGi Core Specification release 4, version 4.1, section 6.1.23; |
| or based on the services themselves (in which case the services must be |
| <code class="interfacename">Comparable</code>).</p><pre class="programlisting"><<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myServices"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MyService"</span>> |
| <<span class="hl-tag">comparator</span>><<span class="hl-tag">natural</span> <span class="hl-attribute">basis</span>=<span class="hl-value">"services"</span>/><<span class="hl-tag">/comparator</span>> |
| <<span class="hl-tag">/list</span>> |
| |
| <<span class="hl-tag">set</span> <span class="hl-attribute">id</span>=<span class="hl-value">"myOtherServices"</span><span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.OtherService"</span>> |
| <<span class="hl-tag">comparator</span>><<span class="hl-tag">natural</span> <span class="hl-attribute">basis</span>=<span class="hl-value">"service-references"</span>/><<span class="hl-tag">/comparator</span>> |
| <<span class="hl-tag">/set</span>></pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">For a sorted set, a <code class="interfacename">SortedSet</code> implementation will be created. |
| However, since the JDK API does not provide a dedicated <code class="interfacename">SortedList</code>interface, |
| the sorted list will implement only the <code class="interfacename">List</code> interface.</td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:collection:greedy-proxying"></a>9.2.3.1. Greedy Proxying</h4></div></div></div><p>All OSGi services imported by a Gemini Blueprint/Spring DM service collection publish and are type-compatible with the classes |
| declared by the <code class="literal">interfaces</code> property. However, some services might expose additional (optional) |
| classes that could be relevant to your application.</p><p>For these cases, Gemini Blueprint/Spring DM collections offer a dedicated attribute called <code class="literal">greedy-proxying</code> which |
| will cause the creates proxies to use <span class="emphasis"><em>all</em></span> the classes advertised by the imported services, visible to the consuming |
| importing bundle. Thus, it is possible to cast the imported proxies to classes different then those specified in the |
| <code class="literal">interfaces</code>. For example, with the following list definition: |
| </p><pre class="programlisting"><<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"services"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.SomeService"</span> <span class="hl-attribute">greedy-proxying</span>=<span class="hl-value">"true"</span>/></pre><p>one can do the following iteration (assuming <code class="classname">MessageDispatcher</code> type is imported by the bundle):</p><pre class="programlisting"><span class="hl-keyword">for</span> (Iterator iterator = services.iterator(); iterator.hasNext();) { |
| SomeService service = (SomeService) iterator.next(); |
| service.executeOperation(); |
| <span class="hl-comment">// if the service implements an additional type</span> |
| <span class="hl-comment">// do something extra</span> |
| <span class="hl-keyword">if</span> (service <span class="hl-keyword">instanceof</span> MessageDispatcher) { |
| ((MessageDispatcher)service).sendAckMessage(); |
| } |
| }</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top">Before using greedy proxies and <code class="literal">instanceof</code> statements, consider using a different |
| interface/class for your services which provides better |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming" target="_top">polymorphism</a> |
| and is more |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://en.wikipedia.org/wiki/Object_oriented" target="_top">object-oriented</a>.</td></tr></table></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:collection:member-type"></a>9.2.3.2. Member Type</h4></div></div></div><p>Since Spring DM 2.x/Gemini Blueprint, service collections can contain either service instances (default) or service references. The latter is useful if |
| the services themselves are not relevant but rather their properties and availability. For example, to track the service references, |
| the following configuration can be used:</p><pre class="programlisting"><<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"services"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.SomeService"</span> <span class="hl-attribute">member-type</span>=<span class="hl-value">"service-reference"</span>/></pre><p>Note that the collection contains <span class="emphasis"><em>native</em></span> service references which can be used by client to retrieve the backing |
| service (if needed). However, when using Gemini Blueprint/Spring DM this use case is discouraged since one can let the framework track the services instead |
| and get the (native) associated service reference from the proxy directly (see <a href="service-registry.html#service-registry:refs:singular:property-editor" title="9.2.2.10. Getting A Hold Of The Managed Service Reference">Section 9.2.2.10, “Getting A Hold Of The Managed Service Reference”</a> |
| for more details).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:collection:attributes"></a>9.2.3.3. Collection (<code class="literal">list</code> And <code class="literal">set</code>) Element Attributes</h4></div></div></div><p> |
| <code class="literal">list</code> and <code class="literal">set</code> elements support all the attributes available to |
| <code class="literal">reference</code> element except the <code class="literal">timeout</code> attribute. |
| |
| See the following table as a summary of the <code class="literal">list</code> and <code class="literal">set</code> element |
| attribute names, possible values and a short description for each of them. |
| </p><div class="table"><a name="collection-import-options"></a><p class="title"><b>Table 9.4. <list>/<set> attributes</b></p><div class="table-contents"><table summary="<list>/<set> attributes" width="100%" border="1"><colgroup><col><col align="center"><col align="center"><col align="center"><col align="center"><col align="justify"></colgroup><thead><tr><th>Name</th><th colspan="4" align="justify">Values</th><th align="justify">Description</th></tr></thead><tbody><tr><td>interface</td><td colspan="4" align="justify">fully qualified class name (such as <code class="classname">java.lang.Thread</code>)</td><td align="justify">The fully qualified name of the class under which the object will be exported.</td></tr><tr><td>filter</td><td colspan="4" align="justify">OSGi filter expression (such as <code class="literal">((asynchronous-delivery=true)</code>)</td><td align="justify">OSGi filter expression that is used to constrain the set of matching services |
| in the service registry.</td></tr><tr><td>bean-name</td><td colspan="4" align="justify">any string value</td><td align="justify">Convenient shortcut for specifying a filter expression that matches on the bean-name property |
| that is automatically advertised for beans published using the <service> element.</td></tr><tr><td>context-class-loader</td><td align="center">client</td><td colspan="2" align="center">service-provider</td><td align="center">unmanaged</td><td align="justify">Defines how the context class loader is managed when invoking operations on a service |
| backing this service reference. The default value is <code class="literal">client</code> which means that the context |
| class loader has visibility of the resources on this bundle's classpath. Alternate |
| options are <code class="literal">service-provider</code> which means that the context class loader has visibility of |
| resources on the bundle classpath of the bundle that exported the service, and <code class="literal">unmanaged</code> |
| which does not do any management of the context class loader.</td></tr><tr><td>availability</td><td colspan="2" align="center">optional</td><td colspan="2" align="center">mandatory</td><td align="justify">Defines the desired availability of the relationship to the backing service. If not specified, |
| the <code class="literal">default-availability</code> attribute will apply. 'mandatory' value (the default) means that a backing service |
| must exist at all times. The 'optional' value indicates that it is acceptable to be for an importer to have no |
| backing service.</td></tr><tr><td>comparator-ref</td><td colspan="4" align="justify">any string value</td><td align="justify">Named reference to a bean acting as comparator for the declaring collection. Declaring a comparator automatically |
| makes the declaring collection sorted.</td></tr><tr><td>greedy-proxying</td><td colspan="2" align="center">true</td><td colspan="2" align="center">false</td><td align="justify">Indicates whether the proxies created for the imported OSGi services will be generated using |
| just the classes specified (<code class="literal">false</code>) or all the classes exported by the service and visible to |
| the importing bundle (<code class="literal">true</code>). The default value is <code class="literal">false</code>.</td></tr><tr><td>member-type</td><td colspan="2" align="center">service-object</td><td colspan="2" align="center">service-reference</td><td align="justify">Indicates the type of object that will be placed within the reference collection. |
| <code class="literal">service-object</code> (the default) indicates the collection contains service proxies for imported services. |
| <code class="literal">service-reference</code> indicates the collection contains <code class="literal">ServiceReference</code> objects matching the |
| target service type.</td></tr></tbody></table></div></div><br class="table-break"><p>The table below lists the attributes available for the <code class="literal">comparator/natural</code> sub element.</p><div class="table"><a name="collection-import-comparator-options"></a><p class="title"><b>Table 9.5. collection <comparator> attributes</b></p><div class="table-contents"><table summary="collection <comparator> attributes" width="100%" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>Name</th><th colspan="2">Values</th><th>Description</th></tr></thead><tbody><tr><td>basis</td><td>service</td><td>service-reference</td><td>Indicate the element on which <span class="emphasis"><em>natural ordering</em></span> should apply - <code class="literal">service</code> for considering |
| the service instance and <code class="literal">service-reference</code> for considering the service reference instead of the service.</td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:collection:dynamics"></a>9.2.3.4. <code class="literal">list</code> / <code class="literal">set</code> And OSGi Service Dynamics</h4></div></div></div><p> |
| A collection of OSGi services will change its content during the lifetime |
| of the application context since it needs to reflect the state of the OSGi |
| space. As service are registered and unregistered, they will be added or |
| removed from the collection.</p><p>While a <code class="literal">reference</code> declaration will try to |
| find a replacement if the backing service is unregistered, the collection |
| will simply remove the service from the collection. |
| Like <code class="literal">reference</code>, a collection of services can have a specified <code class="literal">availability</code>. |
| As opposed to <code class="literal">reference</code>s though, since Spring DM 2.x/Gemini Blueprint, a collection content can be queried, no matter |
| its availability and the number of services held.</p><p>Just like <code class="literal">reference</code>, mandatory collections |
| will trigger the unregistration of any exported service that depends |
| upon it. See |
| <a href="service-registry.html#service-registry:export-import-relationship" title="9.2.1.2. Relationship Between The Service Exporter And Service Importer">Section 9.2.1.2, “Relationship Between The Service Exporter And Service Importer”</a> for more information. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="service-registry:refs:collection:iterator"></a>9.2.3.5. <code class="interfacename">Iterator</code> Contract And Service Collections</h4></div></div></div><p>The recommend way of traversing a collection is by using an <code class="interfacename">Iterator</code>. |
| However, since OSGi services can come and go, the content of the managed service collection will be adjusted |
| accordingly. Gemini Blueprint/Spring DM will transparently update all <code class="interfacename">Iterator</code>s held by |
| the user so it is possible to safely traverse the collection while it is being modified. Moreover, the |
| <code class="interfacename">Iterator</code>s will reflect all the changes made to the collection, even if |
| they occurred after the <code class="interfacename">Iterator</code>s were created (that is during the iteration). |
| Consider a case where a collection shrinks significantly (for example a big number of OSGi |
| services are shutdown) right after an iteration started. |
| To avoid dealing with the resulting 'dead' service references, |
| Gemini Blueprint/Spring DM iterators do not take collection snapshots (that can be inaccurate) |
| but rather are updated on each service event so they reflect the latest collection state, |
| no matter how fast or slow the iteration is.</p><p>It is important to note that a service update will only influence <code class="interfacename">Iterator</code> |
| operations that are executed after the event occurred. Services already returned by the iterator will not be |
| updated even if the backing service has been unregistered. As a side note, if an operation is invoked on |
| such a service that has been unregistered, a <code class="literal">ServiceUnavailableException</code> will be thrown. |
| </p><p>To conclude, while a <code class="literal">reference</code> declaration will search for candidates in case the |
| backing service has been unregistered, a service collections will not replace unregistered services returned |
| to the user. However, it will remove the unregistered services from the collection so future iterations will not |
| encounter them. |
| </p><p>Please note that the <code class="interfacename">Iterator</code> contract is guaranteed meaning that |
| <code class="literal">next()</code> method <span class="emphasis"><em>always</em></span> obey the result of the previous |
| <code class="literal">hasNext()</code> invocation.</p><div class="table"><a name="collection-iterator-contract"></a><p class="title"><b>Table 9.6. Dynamic service collection <code class="interfacename">Iterator</code> contract</b></p><div class="table-contents"><table summary="Dynamic service collection Iterator contract" width="100%" border="1"><colgroup><col><col></colgroup><thead><tr><th>hasNext() returned value</th><th>next() behaviour</th></tr></thead><tbody><tr><td>true</td><td><span class="emphasis"><em>Always</em></span> return a non-null value, even when the collection has shrunk as services when away. |
| </td></tr><tr><td>false</td><td>per <code class="interfacename">Iterator</code> contract, <code class="classname">NoSuchElementException</code> is thrown. |
| This applies even if other services are added to the collection</td></tr></tbody></table></div></div><br class="table-break"><p> |
| The behaviour described above, offers a consistent view over the collection even if its structure changes during iteration. |
| To simply <span class="emphasis"><em>refresh</em></span> the iterator, call <code class="literal">hasNext()</code> again. This will force the |
| <code class="literal">Iterator</code> to check again the collection status for its particular entry in the iteration.</p><p> |
| In addition, any elements added to the collection during iteration over a <span class="emphasis"><em>sorted</em></span> |
| collection will only be visible if the iterator has not already passed |
| their sort point.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:dynamics"></a>9.2.4. Dealing With The Dynamics Of OSGi Imported Services</h3></div></div></div><div class="sidebar"><p class="title"><b>Where is the <code class="literal">listener</code> element ?</b></p><p>Since Spring DM 2.x/Gemini Blueprint, the <code class="literal">reference-listener</code> replaced |
| the <code class="literal">listener</code> element which has been deprecated. The main reasons |
| behind the decisions were to align the configuration format closer with the Blueprint |
| spec and to avoid some of the confusion regarding the type of listener declared (service or reference |
| based). Note that <code class="literal">listener</code> element is still supported.</p></div><p>Whether you are using <code class="literal">reference</code> |
| or <code class="literal">set</code> or <code class="literal">list</code>, Spring Dynamic |
| Modules will manage the backing service. However there are cases |
| where the application needs to be aware when the backing service |
| is updated.</p><p>Such applications, that need to be aware of when the service |
| backing a <code class="literal">reference</code> bean is bound and unbound, can |
| register one or more listeners using the nested |
| <code class="literal">reference-listener</code> (or <code class="literal">listener</code>) element. |
| This element is available on both <code class="literal">reference</code> and |
| <code class="literal">set</code>, <code class="literal">list</code> declarations. |
| In many respects, the service importer listener declaration |
| is similar to the service exporter listener declaration |
| (<a href="service-registry.html#service-registry:export:lifecycle" title="9.1.10. Service Registration And Unregistration Lifecycle">Section 9.1.10, “Service Registration And Unregistration Lifecycle”</a>). |
| |
| The <code class="literal">reference-listener</code> element refers to a bean (either by name, |
| or by defining one inline) |
| that will receive bind and unbind notifications. If this bean |
| implements Gemini Blueprint/Spring DM's |
| <code class="interfacename">org.eclipse.gemini.blueprint.service.importer.OsgiServiceLifecycleListener</code> |
| interface, then the <code class="literal">bind</code> and |
| <code class="literal">unbind</code> operations in this interface will be |
| invoked. Instead of implementing this interface (or in addition), |
| custom bind and unbind callback methods may be named.</p><p>An example of declaring a listener that implements |
| <code class="interfacename">OsgiServiceLifecycleListener</code>:</p><pre class="programlisting"><<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>> |
| <<span class="hl-tag">reference-listener</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"aListenerBean"</span>/> |
| <<span class="hl-tag">/reference</span>></pre><p>An example of declaring an inline listener bean with custom |
| bind and unbind methods:</p><pre class="programlisting"><<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.MessageService"</span>> |
| <<span class="hl-tag">reference-listener</span> <span class="hl-attribute">bind-method</span>=<span class="hl-value">"onBind"</span> <span class="hl-attribute">unbind-method</span>=<span class="hl-value">"onUnbind"</span>> |
| <<span class="hl-tag">beans:bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"MyCustomListener"</span>/> |
| <<span class="hl-tag">/reference-listener</span>> |
| <<span class="hl-tag">/reference</span>></pre><p>If the listener bean implements the |
| <code class="interfacename">OsgiServiceLifecycleListener</code> interface |
| <span class="emphasis"><em>and</em></span> the listener definition specifies custom |
| bind and unbind operations then both the |
| <code class="literal">OsgiServiceLifecycleListener</code> operation and the |
| custom operation will be invoked, in that order.</p><p>The signature of a custom bind or unbind method must be one |
| of:</p><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(ServiceType service, Dictionary properties); |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(ServiceType service, Map properties); |
| |
| <span class="hl-keyword">public</span> <span class="hl-keyword">void</span> anyMethodName(ServiceReference ref);</pre><p>where <code class="literal">ServiceType</code> can be any type. Please note that |
| bind and unbind callbacks are invoked <span class="emphasis"><em>only</em></span> |
| if the backing service matches the type declared in the method signature( |
| <code class="classname">ServiceType</code>). If you want the callbacks to be called |
| no matter the type, use <code class="classname">java.lang.Object</code> as a |
| <code class="literal">ServiceType</code>.</p><p> |
| The <code class="literal">properties</code> parameter contains the set of properties |
| that the service was registered with.</p><p>If the method signature has a single argument of type |
| <code class="interfacename">ServiceReference</code> then the |
| <code class="interfacename">ServiceReference</code> of the service will be passed to |
| the callback in place of the service object itself.</p><p>When the listener is used with a <code class="literal">reference</code> declaration:</p><div class="itemizedlist"><ul type="disc"><li>A <span class="emphasis"><em>bind</em></span> callback is invoked |
| when the reference is initially bound to a backing service, |
| and whenever the backing service is replaced by a new backing service. |
| </li><li>An <span class="emphasis"><em>unbind</em></span> callback is only |
| invoked when the current backing service is unregistered, and no |
| replacement service is immediately available |
| (i.e., the <code class="literal">reference</code> becomes unsatisfied).</li></ul></div><p>When the listener is used with a collection declaration (<code class="literal">set</code> or |
| <code class="literal">list</code>):</p><div class="itemizedlist"><ul type="disc"><li>A <span class="emphasis"><em>bind</em></span> callback is invoked |
| when a new service is added to the collection. |
| </li><li>An <span class="emphasis"><em>unbind</em></span> callback is |
| invoked when a service is unregistered and is removed |
| from the collection.</li></ul></div><p>Again note that service collections there is <span class="emphasis"><em>no</em></span> |
| notion of <span class="emphasis"><em>service rebind</em></span>: |
| services are added or removed from the collection.</p><p>Bind and unbind callbacks are made synchronously as part of |
| processing an OSGi <code class="literal">serviceChanged</code> event for the |
| backing OSGi service, and are invoked on the OSGi thread that |
| delivers the corresponding OSGi |
| <code class="classname">ServiceEvent</code>.</p><p>The table below lists the attributes available for the <code class="literal">reference</code> <code class="literal">listener</code> sub element.</p><div class="table"><a name="reference-import-listener-options"></a><p class="title"><b>Table 9.7. OSGi <reference-listener> attributes</b></p><div class="table-contents"><table summary="OSGi <reference-listener> attributes" width="100%" border="1"><colgroup><col><col><col></colgroup><thead><tr><th>Name</th><th>Values</th><th>Description</th></tr></thead><tbody><tr><td>ref</td><td>bean name reference</td><td>Name based reference to another bean acting as listener.</td></tr><tr><td>bind-method</td><td>string representing a valid method name</td><td>The name of the method to be invoked when a backing service is bound.</td></tr><tr><td>unbind-method</td><td>string representing a valid method name</td><td>The name of the method to be invoked when a backing service is bound.</td></tr></tbody></table></div></div><br class="table-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:blueprint"></a>9.2.5. Blueprint <code class="literal">reference</code> Comparison</h3></div></div></div><p>Similar to Gemini Blueprint/Spring DM, the Blueprint Container offers a <code class="literal">reference</code> and <code class="literal">list</code> elements, |
| identical in functionality with the those in Gemini Blueprint/Spring DM. Below is a summary of the configuration options available in Gemini Blueprint/Spring DM and Blueprint:</p><div class="table"><a name="service-registry:refs:blueprint:comparison"></a><p class="title"><b>Table 9.8. Spring DM / Blueprint Service Importer Configuration Comparison</b></p><div class="table-contents"><table summary="Spring DM / Blueprint Service Importer Configuration Comparison" width="100%" border="1"><colgroup><col><col></colgroup><thead><tr><th align="center">Gemini Blueprint/Spring DM</th><th align="center">Blueprint</th></tr></thead><tbody><tr><td align="center">Common Elements/Attributes</td><td class="auto-generated"> </td></tr><tr><td align="center">interface</td><td align="center">interface</td></tr><tr><td align="center">interfaces</td><td align="center">- (multiple interfaces not supported)</td></tr><tr><td align="center">ref</td><td align="center">ref</td></tr><tr><td align="center">filter</td><td align="center">filter</td></tr><tr><td align="center">bean-name</td><td align="center">component-name</td></tr><tr><td align="center">availability</td><td align="center">availability</td></tr><tr><td align="center">context-class-loader</td><td align="center">-</td></tr><tr><td align="center"><code class="literal"><reference></code></td><td class="auto-generated"> </td></tr><tr><td align="center">timeout</td><td align="center">timeout</td></tr><tr><td align="center">sticky</td><td align="center">- (the importer is always sticky)</td></tr><tr><td align="center"><code class="literal"><list></code></td><td class="auto-generated"> </td></tr><tr><td align="center">member-type</td><td align="center">member-type</td></tr><tr><td align="center">comparator-ref</td><td align="center">-</td></tr><tr><td align="center">greedy-proxying</td><td align="center">-</td></tr></tbody></table></div></div><br class="table-break"><p>Since the <code class="literal">registration-listener</code> declaration is identical in declaration and functionality between Blueprint |
| and Gemini Blueprint/Spring DM, this section does not mention it.</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:refs:listener-and-proxies"></a>9.3. Listener And Service Proxies</h2></div></div></div><p>While the importer listener provides access to the OSGi service bound at a certain point, it is important to note that the given argument is <span class="emphasis"><em>not</em></span> |
| the actual service but a <span class="emphasis"><em>proxy</em></span>. This can have subtle side effects especially with regards to service class name |
| and identity. The reason behind using a proxy is to prevent the listener from holding strong reference to the service (which can disappear |
| at any point). Listeners interested in tracking certain services should not rely on instance equality (<code class="literal">==</code>). Object equality |
| (<code class="methodname">equals</code>/<code class="methodname">hashcode</code>) can be used but only if the backing service has exposed the aforementioned methods |
| as part of its contract (normally by declaring them on a certain published interface/class). If these methods are not published, the proxy will invoke its own method, not the targets. This is on purpose since, |
| while the proxy tries to be as transparent as possible, it is up to the developer to define the desired semantics. |
| </p><p>Thus, it is recommended (especially for <code class="literal">reference</code> importers) to do tracking based on just the service interface/contract |
| (not identity), service properties (see <code class="constant">org.osgi.framework.Constants#SERVICE_ID</code>) or service notification (bind/unbind).</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:refs:invoker-bundle-context"></a>9.4. Accessing The Caller <code class="interfacename">BundleContext</code></h2></div></div></div><p>It is sometimes useful for an imported service to know which bundle is using it |
| at a certain time. To help with this scenario, in Gemini Blueprint/Spring DM imported services publish |
| the importing bundle <code class="interfacename">BundleContext</code> through |
| <code class="classname">LocalBundleContext</code> class. Each time a method on the importer is invoked, |
| the caller <code class="interfacename">BundleContext</code> will be made available, using |
| a <code class="classname">ThreadLocal</code>, through <code class="methodname">getInvokerBundleContext()</code>. |
| </p><p>Please be careful when using this class since it ties your code to Gemini Blueprint/Spring DM API.</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:refs:listener-best-practices"></a>9.5. Exporter/Importer Listener Best Practices</h2></div></div></div><p>As mentioned above, Gemini Blueprint/Spring DM exporter and importer allow listeners to be |
| used for receiving notifications on when services are bound, unbound, registered or |
| unregistered. Below you can find some guidance advices when working with listeners: |
| </p><div class="itemizedlist"><ul type="disc"><li> |
| Do <span class="emphasis"><em>not</em></span> execute long activity tasks inside the listener. If you really |
| have to, use a separate thread for executing the work. The listener are called synchronously |
| and so try to be as fast as possible. Doing work inside the listener prevents other the event |
| to be sent to other listeners and the OSGi service to resume activity. |
| </li><li>Use listener custom declaration as much as possible - it doesn't tie your code |
| to Gemini Blueprint/Spring DM API and it doesn't enforce certain signature names.</li><li>If find yourself repeating bind/unbind method declarations for your listener definitions, |
| consider using Spring <a xmlns:xlink="http://www.w3.org/1999/xlink" href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-child-bean-definitions" target="_top"> |
| bean definition inheritance</a> to define a common definition that can be reused and customized |
| accordingly. |
| </li><li>Prefer <code class="interfacename">java.util.Map</code> instead of <code class="classname">java.util.Dictionary</code> |
| class. The first is an interface while the latter is a deprecated, abstract class. To preserve compatibility, Gemini Blueprint/Spring DM |
| will pass to the listeners a <code class="interfacename">Map</code> implementation that can be casted, if needed, to a |
| <code class="classname">Dictionary</code>.</li><li>Be careful when using overloaded methods: all methods matching a certain service type will be called which is not |
| always expected. Consider the following listener: |
| <div class="programlistingco"><pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">class</span> MyListener { |
| <span class="hl-keyword">void</span> register(<span class="co"><img src="images/callouts/1.png" alt="(1)"></span>Object service, Map properties); |
| <span class="hl-keyword">void</span> register(<span class="co"><img src="images/callouts/2.png" alt="(2)"></span>Collection dataService, Map properties); |
| <span class="hl-keyword">void</span> register(<span class="co"><img src="images/callouts/3.png" alt="(3)"></span>SortedSet orderedDataService , Map properties); |
| }</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><a name="service-registry:refs:listener:type.1"></a><p><code class="classname">Object</code> type - will match all services for which the listener is triggered. This method will be always called.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><a name="service-registry:refs:listener:type.2"></a><p><code class="classname">Collection</code> type - if this method is called, the <a href="service-registry.html#service-registry:refs:listener:type.1"> |
| <code class="classname">Object</code> method</a> is also called. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><a name="service-registry:refs:listener:type.3"></a><p><code class="classname">SortedSet</code> type - if this method is called, then both the <a href="service-registry.html#service-registry:refs:listener:type.1"> |
| <code class="classname">Object</code></a> and <a href="service-registry.html#service-registry:refs:listener:type.2"><code class="classname">Collection</code></a> |
| methods are called.</p></td></tr></table></div></div></li></ul></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="service-registry:refs:listener-best-practices:cycles"></a>9.5.1. Listener And Cyclic Dependencies</h3></div></div></div><p>There are cases where an exporter/importer listener needs a reference back to the bean it is defined on:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">bean</span> <span class="hl-attribute">id</span>=<span class="hl-value">"listener"</span> <span class="hl-attribute">class</span>=<span class="hl-value">"cycle.Listener"</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"target"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"importer"</span> /> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <<span class="hl-tag">/bean</span>> |
| |
| <<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"importer"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"SomeService"</span>> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <<span class="hl-tag">osgi:listener</span> <span class="hl-attribute">bind-method</span>=<span class="hl-value">"bind"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"listener"</span> /> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <<span class="hl-tag">/osgi:reference</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Listener bean</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Dependency listener -> importer</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Importer declaration</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Dependency importer -> listener</p></td></tr></table></div></div><p> |
| The declaration above while valid, creates a dependecy between the <code class="literal">listener</code> and the importer it is defined upon. |
| In order to create the importer, the <code class="literal">listener</code> has to be resolved and created but in order to do that, |
| the importer called <code class="literal">service</code> needs to be retrieved (instantiated and configured). This cycle needs to be broken |
| down so that at least one bean can be fully created and configured. This scenario is supported by Gemini Blueprint/Spring DM |
| for both exporter and importers however, if the listener is defined as a nested bean, the cycle cannot be resolved:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">osgi:reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"importer"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"SomeService"</span>> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <<span class="hl-tag">osgi:listener</span> <span class="hl-attribute">bind-method</span>=<span class="hl-value">"bind"</span>> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <<span class="hl-tag">bean</span> <span class="hl-attribute">class</span>=<span class="hl-value">"cycle.Listener"</span>> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <<span class="hl-tag">property</span> <span class="hl-attribute">name</span>=<span class="hl-value">"target"</span> <span class="hl-attribute">ref</span>=<span class="hl-value">"importer"</span> /> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <<span class="hl-tag">/bean</span>> |
| <<span class="hl-tag">/osgi:listener</span>> |
| <<span class="hl-tag">/osgi:reference</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>OSGi service importer</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Dependency between importer -> listener</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Nested listener declaration</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Dependency nested listener -> importer</p></td></tr></table></div></div><div class="sidebar"><p class="title"><b>Beans and Cycles</b></p><p> |
| Cyclic dependencies (A depends on B which depends back on A) increase the complexity of your configuration |
| and in most cases indicate a design issue. What beans should be created and destroyed first for example? |
| While they are a bad practice, the Spring container makes a best attempt to solve the cyclic configurations |
| when singletons are involved (since the instances can be cached). However this does not work all the time and |
| depends heavily on your specific configuration (Can the bean class be partially initialized ? Does it rely on |
| special <code class="interfacename">Aware</code> interfaces? Are <code class="interfacename">BeanPostProcessor</code>s involved?) |
| </p></div><p>The example above will fail since <code class="literal">service</code> bean cannot be initialized as it depends on the |
| listener. The same cycle was seen before but in this case there is subtle yet big different from |
| the container perspective - the listener is declared as a nested/inner-bean (hence the missing bean <code class="literal">id</code>). |
| Inner beans have the same life cycle as their declaring parents and do not have any name. By definition, they are not tracked |
| by the container and are simply created on demand. Since the importer cannot be partially created and the nested listener cannot |
| be cached, the container cannot break the cycle and create the beans. While the two configurations shown above seem similar, one works |
| while the other does not. Another reason to not use cycles unless you really, really have to.</p><p>To conclude, if you need inside the listener to hold a reference to the exporter/importer on which the listener is declared, |
| either declare the listener as a <span class="emphasis"><em>top-level</em></span> bean (as shown before) or consider doing <span class="emphasis"><em>dependency lookup</em></span>. |
| However, the latter approach requires extra contextual information such as the <code class="interfacename">BeanFactory</code> to use and the bean |
| name and is more fragile then <span class="emphasis"><em>dependency injection</em></span>.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/admons/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><p>For those interested in the technical details, neither the exporter and importer cannot be partially initialized since |
| they require the application context <code class="classname">ClassLoader</code> which is requested through the |
| <code class="interfacename">BeanClassLoaderAware</code> which relies on a buit-in <code class="interfacename">BeanPostProcessor</code> |
| which is applied only after the bean has been configured and is ready for initialization. If the <code class="classname">ClassLoader</code> |
| was not required then the exporter/importer could have been partially initialized and the case above supported.</p></td></tr></table></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="service-registry:refs:global-defaults"></a>9.6. Service Importer Global Defaults</h2></div></div></div><p>The <code class="literal">osgi</code> namespace offers two |
| global attributes for specifying default behaviours for all |
| importers declared in that file.</p><p>Thus, when using the <code class="literal">osgi</code> namespace to enclose |
| <code class="literal">set</code>, <code class="literal">list</code> or |
| <code class="literal">reference</code> elements, one can use:</p><div class="itemizedlist"><ul type="disc"><li><p><code class="literal">default-timeout</code> - |
| can be used to specify the default timeout (in milliseconds) for all |
| importer elements that do not explicitly specify one. For |
| example:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:osgi</span>=<span class="hl-value">"http://www.springframework.org/schema/osgi"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">osgi:default-timeout</span>=<span class="hl-value">"5000"</span>> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| |
| <<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.AService"</span>/> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| |
| <<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someOtherService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.BService"</span> |
| <span class="hl-attribute">timeout</span>=<span class="hl-value">"1000"</span>/> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| |
| <<span class="hl-tag">/beans:beans</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Declare <code class="literal">osgi</code> namespace prefix.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Declare <code class="literal">default-timeout</code>(in miliseconds) on the root element. |
| If the default is not set, it will have a value of 5 minutes. In this example, the |
| default value is 5 seconds.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>This <code class="literal">reference</code> will inherit the default timeout value since |
| it does not specify one. |
| This service reference will have a timeout of 5 seconds.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>This <code class="literal">reference</code> declares a timeout, overriding the default value. |
| This service reference will have a timeout of 1 second.</p></td></tr></table></div></div></li><li><p><code class="literal">default-availability</code> - |
| can be used to specify the default availability for all |
| importer elements that do not explicitly specify one. |
| Possible values are <code class="literal">optional</code> and <code class="literal">mandatory</code>. |
| The <code class="literal">default-cardinality</code> attribute, used by Spring DM 1.x, is still |
| available but it has been deprecated. |
| </p><p>Consider the following example:</p><div class="programlistingco"><pre class="programlisting"><<span class="hl-tag">beans:beans</span> |
| <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/osgi"</span> <span class="co"><img src="images/callouts/1.png" alt="(1)"></span> |
| <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span> |
| <span class="hl-attribute">xmlns:beans</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span> <span class="co"><img src="images/callouts/2.png" alt="(2)"></span> |
| <span class="hl-attribute">xmlns:osgi</span>=<span class="hl-value">"http://www.springframework.org/schema/osgi"</span> <span class="co"><img src="images/callouts/3.png" alt="(3)"></span> |
| <span class="hl-attribute">osgi:default-availability</span>=<span class="hl-value">"optional"</span> <span class="co"><img src="images/callouts/4.png" alt="(4)"></span> |
| <span class="hl-attribute">default-lazy-init</span>=<span class="hl-value">"false"</span>> <span class="co"><img src="images/callouts/5.png" alt="(5)"></span> |
| |
| <<span class="hl-tag">reference</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.AService"</span>/> <span class="co"><img src="images/callouts/6.png" alt="(6)"></span> |
| |
| <<span class="hl-tag">set</span> <span class="hl-attribute">id</span>=<span class="hl-value">"someSetOfService"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.BService"</span>/> <span class="co"><img src="images/callouts/7.png" alt="(7)"></span> |
| |
| <<span class="hl-tag">list</span> <span class="hl-attribute">id</span>=<span class="hl-value">"anotherListOfServices"</span> <span class="hl-attribute">interface</span>=<span class="hl-value">"com.xyz.CService"</span> |
| <span class="hl-attribute">availability</span>=<span class="hl-value">"mandatory"</span>/> <span class="co"><img src="images/callouts/8.png" alt="(8)"></span> |
| |
| <<span class="hl-tag">/beans:beans</span>></pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><img src="images/callouts/1.png" alt="1" border="0"></td><td valign="top" align="left"><p>Declare Gemini Blueprint schema as the default namespace.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/2.png" alt="2" border="0"></td><td valign="top" align="left"><p>Import Spring Framework beans schema and associate a prefix with its namespace |
| (<code class="literal">beans</code> in this example).</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/3.png" alt="3" border="0"></td><td valign="top" align="left"><p>Import Gemini Blueprint schema and associate a prefix with its namespace |
| (<code class="literal">osgi</code> in this example). This is required since the global attributes |
| have to be declared to an element (<code class="literal">beans</code>) belonging to another schema. |
| To avoid ambiguity, the Gemini Blueprint/Spring DM schema is imported under a specified prefix as well.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/4.png" alt="4" border="0"></td><td valign="top" align="left"><p>Declare <code class="literal">default-availability</code> on the root element. |
| If the default is not set, it will have a value of <code class="literal">mandatory</code>. In this example, the |
| default value is <code class="literal">optional</code>. Note the <code class="literal">osgi</code> prefix added to |
| the global attribute.</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/5.png" alt="5" border="0"></td><td valign="top" align="left"><p><code class="literal">beans</code> element attributes (such as <code class="literal">default-lazy-init</code>) |
| do not need a prefix since they are declared as being local and unqualified |
| (see the beans schema for more information).</p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/6.png" alt="6" border="0"></td><td valign="top" align="left"><p> |
| The <code class="literal">reference</code> declaration will inherit the default availability value since it does not specify one. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/7.png" alt="7" border="0"></td><td valign="top" align="left"><p> |
| The <code class="literal">set</code> declaration will inherit the default availability value since it does not specify one. |
| </p></td></tr><tr><td width="5%" valign="top" align="left"><img src="images/callouts/8.png" alt="8" border="0"></td><td valign="top" align="left"><p>The <code class="literal">list</code> declaration specifies its availability (<code class="literal">mandatory</code>), |
| overriding the default value.</p></td></tr></table></div></div></li></ul></div><p>The <code class="literal">default-*</code> attributes allow for concise and shorter declarations as well |
| as easy propagation of changes (such as increasing or decreasing the timeout).</p></div></div><div xmlns:fo="http://www.w3.org/1999/XSL/Format" class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-deploy.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="bundles.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 8. Packaging and Deploying Spring-based OSGi applications </td><td width="20%" align="center"><span style="color:white;font-size:90%;"><a href="http://www.SpringSource.com/" title="SpringSource - Spring from the Source">Sponsored by SpringSource |
| </a></span></td><td width="40%" align="right" valign="top"> Chapter 10. Working With Bundles</td></tr></table></div></body></html> |