felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > Providing OSGi services
Date Thu, 06 May 2010 07:45:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="http://cwiki.apache.org/confluence/display/FELIX/Providing+OSGi+services">Providing
OSGi services</a></h2>
    <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~clement.escoffier">Clement
Escoffier</a>
    </h4>
        <br/>
                         <h4>Changes (2)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >The component can also publish itself
as a service. However, such practice are not recommended. <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >h3. Controlling the service exposition
<span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">form</span>
<span class="diff-added-words"style="background-color: #dfd;">from</span> the
implementation class <br></td></tr>
            <tr><td class="diff-unchanged" > <br>This handler also allows
the injection of a &#39;service controller&#39;. The injected boolean field allows
the code to impact the service publication. Setting the field to {{false}} unregisters the
service from the service registry. Setting it back to {{true}} re-publishes the service. <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >    // ... <br>{code} <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">
<br>h3. Being notified of the service registration and unregistration (new in the 1.7.0-SNAPSHOT)
<br>This handler also proposed a way to the implementation class to be notified when
the services a published and unpublished.This is done byu specifying the two callback in the
{{&lt;provides/&gt;}} element: <br>{code:xml} <br>&lt;component <br>
    classname=&quot;org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService&quot;
<br>     name=&quot;PS-Callbacks-both-1&quot;&gt; <br>    &lt;provides
<br>	specifications=&quot;org.apache.felix.ipojo.test.scenarios.ps.service.FooService&quot;
<br>	post-unregistration=&quot;unregistered&quot; post-registration=&quot;registered&quot;/&gt;
<br>    &lt;provides <br>	specifications=&quot;org.apache.felix.ipojo.test.scenarios.ps.service.CheckService&quot;
<br>	post-unregistration=&quot;unregistered&quot; post-registration=&quot;registered&quot;/&gt;
<br>&lt;/component&gt; <br>{code} <br> <br>Each {{provides}}
element can specify: <br>* a {{post-registration}} callback : called after the service
publication <br>* a {{post-unregistration}} callback : called after the service unpublication
<br> <br>Those attributes specify the method name to call. Those method must have
the following signature: {{public void name(ServiceReference ref)}}. So they receive the published
/ unpublished service reference. The callbacks are called in the same thread as the publication
/ unpublication itself.  <br> <br>It is also possible to use annotations to specify
such callbacks: <br>{code:java} <br>	@PostRegistration <br>	public void
registered(ServiceReference ref) { <br>		System.out.println(&quot;Registered&quot;);
<br>	} <br> <br>        @PostUnregistration <br>	public void unregistered(ServiceReference
ref) { <br>		System.out.println(&quot;Unregistered&quot;); <br>	} <br>{code}
<br></td></tr>
            <tr><td class="diff-unchanged" >\\ <br>\\ <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <style type="text/css">
 @import url(http://felix.apache.org/ipojo/site/superfish.css); 
</style>

<style type="text/css">
 @import url(http://felix.apache.org/ipojo/site/style.css); 
</style>

<p>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shCore.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushCSharp.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushPhp.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushJScript.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushVb.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushSql.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushXml.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushShell.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushDelphi.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushPython.js"></script>
<script class="javascript" src="http://cwiki.apache.org/confluence/download/resources/confluence.ext.code:code/shBrushJava.js"></script>

<script type="text/javascript" src="http://felix.apache.org/ipojo/site/jquery-1.js"></script>
<script type="text/javascript" src="http://felix.apache.org/ipojo/site/hoverIntent.js"></script>
<script type="text/javascript" src="http://felix.apache.org/ipojo/site/superfish.js"></script>

<script type="text/javascript" src="http://felix.apache.org/ipojo/site/supersubs.js"></script>


<script type="text/javascript"> 
 
    $(document).ready(function(){ 
        $("ul.sf-menu").supersubs({ 
            minWidth:    14,   // minimum width of sub-menus in em units 
            maxWidth:    30,   // maximum width of sub-menus in em units 
            extraWidth:  1     // extra width can ensure lines don't sometimes turn over 
                               // due to slight rounding differences and font-family 
        }).superfish();  // call supersubs first, then superfish, so that subs are 
                         // not display:none when measuring. Call before initialising 
                         // containing tabs for same reason. 
    }); 
 
</script>
<div class="main">
<div class="page-header"/>
<img src="http://felix.apache.org/ipojo/site/header.png" class="header">
<a href="http://ipojo.org"><img src="http://felix.apache.org/ipojo/site/ipojo.png"
width="225" class="header-logo"></a>
<ul class="sf-menu sf-js-enabled sf-shadow" id="ipojo-menu">
<li class="current">
<!-- Menu Overview -->
<a href="#" class="sf-with-ul">Overview<span class="sf-sub-indicator"> »</span><span
class="sf-sub-indicator"> »</span></a>
<ul>
	<li>
	<a href="/confluence/display/FELIX/Apache+Felix+iPOJO" title="Apache Felix iPOJO">Home</a>
						
	</li>
	<li>
	<a href="/confluence/display/FELIX/apache-felix-ipojo-why-choose-ipojo" title="apache-felix-ipojo-why-choose-ipojo">Why
choose iPOJO</a>
	</li>
	<li>
	<a href="/confluence/display/FELIX/apache-felix-ipojo-successstories" title="apache-felix-ipojo-successstories">Success
stories</a>
	</li>
	<li>
	<a href="/confluence/display/FELIX/Apache+Felix+iPOJO+Feature+Overview" title="Apache
Felix iPOJO Feature Overview">Features</a>
	</li>
</ul>
</li>	

<li class="">			
<!-- Menu download -->
<li>
<a href="/confluence/display/FELIX/Download" title="Download">Download </a>
</li>

<li class="">					
<!-- Menu Documentation -->
<a href="#" class="sf-with-ul">Documentation<span class="sf-sub-indicator"> »</span><span
class="sf-sub-indicator"> »</span></a>
<ul>
    <!-- sub-menu : getting started -->
    <li class="">
    <a href="#" class="sf-with-ul">Getting Started<span class="sf-sub-indicator">
»</span><span class="sf-sub-indicator"> »</span></a>
    <ul>
     <li><a href="/confluence/display/FELIX/iPOJO+in+10+minutes" title="iPOJO in
10 minutes">iPOJO in 10 minutes</a></li>
     <li><a href="/confluence/display/FELIX/How+to+use+iPOJO+Annotations" title="How
to use iPOJO Annotations">Using Annotations</a></li>
     <li><a href="/confluence/display/FELIX/iPOJO+Hello+Word+%28Maven-Based%29+tutorial"
title="iPOJO Hello Word (Maven-Based) tutorial">Maven tutorial</a></li>
     <li><a href="/confluence/display/FELIX/iPOJO+Advanced+Tutorial" title="iPOJO
Advanced Tutorial">Advanced tutorial</a></li>
     <li><a href="/confluence/display/FELIX/apache-felix-ipojo-dosgi" title="apache-felix-ipojo-dosgi">Using
Distributed OSGi</a></li>
     <li><a href="/confluence/display/FELIX/iPOJO+Composition+Tutorial" title="iPOJO
Composition Tutorial">Application Composition</a></li>
    </ul>
    </li> <!-- end of getting started -->
    <!-- sub menu : Describing Components -->
     <li class="">
        <a href="http://felix.apache.org/site/describing-components.html" class="sf-with-ul">Describing
components<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator">
»</span></a>
        <ul>
        <li><a href="/confluence/display/FELIX/Service+Requirement+Handler" title="Service
Requirement Handler">Requiring a service</a></li>
        <li><a href="/confluence/display/FELIX/Providing+OSGi+services" title="Providing
OSGi services">Providing a service</a></li>
        <li><a href="/confluence/display/FELIX/Lifecycle+Callback+Handler" title="Lifecycle
Callback Handler">Lifecycle management</a></li>
        <li><a href="/confluence/display/FELIX/Configuration+Handler" title="Configuration
Handler">Configuration</a></li>
        <li><a href="/confluence/display/FELIX/Architecture+Handler" title="Architecture
Handler">Introspection</a></li>
        <li><a href="/confluence/display/FELIX/Controller+Lifecycle+Handler" title="Controller
Lifecycle Handler">Impacting the lifecycle</a></li>
        <li><a href="/confluence/display/FELIX/Event+Admin+Handlers" title="Event
Admin Handlers">Asynchronous communication</a></li>
        <li><a href="/confluence/display/FELIX/iPOJO+JMX+Handler" title="iPOJO JMX
Handler">JMX management</a></li>
        <li><a href="/confluence/display/FELIX/Extender+Pattern+Handler" title="Extender
Pattern Handler">Extender pattern</a></li>
        <li><a href="/confluence/display/FELIX/White+Board+Pattern+Handler" title="White
Board Pattern Handler">Whiteboard pattern</a></li>
        <li><a href="/confluence/display/FELIX/Temporal+Service+Dependency" title="Temporal
Service Dependency">Temporal dependencies</a></li>
        </ul>
     </li> <!-- End of describing components -->
    <!-- sub-menu : User Guide -->
    <li class="">
    <a href="" class="sf-with-ul">User Guide<span class="sf-sub-indicator"> »</span><span
class="sf-sub-indicator"> »</span></a>
        <ul>
        <li><a href="/confluence/display/FELIX/Combining+iPOJO+and+Configuration+Admin"
title="Combining iPOJO and Configuration Admin">iPOJO and config admin</a></li>
        <li><a href="/confluence/display/FELIX/How-to+use+iPOJO+factories" title="How-to
use iPOJO factories">Factories and Instances</a></li>
        <li><a href="/confluence/display/FELIX/Using+XML+Schemas" title="Using XML
Schemas">XML Schemas</a></li>
        <li><a href="/confluence/display/FELIX/apache-felix-ipojo-api" title="apache-felix-ipojo-api">API</a></li>
        <li><a href="/confluence/display/FELIX/apache-felix-ipojo-testing-components"
title="apache-felix-ipojo-testing-components">Testing components</a></li>
        <li><a href="/confluence/display/FELIX/apache-felix-ipojo-eclipse-integration"
title="apache-felix-ipojo-eclipse-integration">Eclipse Integration</a></li>
        <li><a href="/confluence/display/FELIX/iPOJO+FAQ" title="iPOJO FAQ">FAQ</a></li>
        <li><a href="/confluence/display/FELIX/iPOJO-Reference-Card" title="iPOJO-Reference-Card">Reference
Card</a></li>
        </ul>
    </li> <!-- end of user guide -->
    <!-- sub-menu : Dev Guide -->
    <li> 
    <a href="#" class="sf-with-ul">Advanced Topics<span class="sf-sub-indicator">
»</span><span class="sf-sub-indicator"> »</span></a>
       <ul>
        <li><a href="http://felix.apache.org/ipojo/api/1.6.0" class="external-link"
rel="nofollow">Javadoc</a></li>
        <li><a href="/confluence/display/FELIX/How+to+write+your+own+handler" title="How
to write your own handler">Handler development</a></li>
        <li><a href="/confluence/display/FELIX/How+to+use+iPOJO+Manipulation+Metadata"
title="How to use iPOJO Manipulation Metadata">Manipulation Metadata </a></li>
        <li><a href="/confluence/display/FELIX/Dive+into+the+iPOJO+Manipulation+depths"
title="Dive into the iPOJO Manipulation depths">Dive into the iPOJO Manipulation depths</a></li>
       </ul>
    </li> <!-- End of Dev guide -->
</ul> 
</li> <!-- End of doc -->
<!-- Menu 4 : Tools -->
<li class="">
<a href="#" class="sf-with-ul">Tools<span class="sf-sub-indicator"> »</span><span
class="sf-sub-indicator"> »</span></a>
<ul>
   <li><a href="/confluence/display/FELIX/iPOJO+Ant+Task" title="iPOJO Ant Task">Ant
Task</a></li>
   <li><a href="/confluence/display/FELIX/iPOJO+Eclipse+Plug-in" title="iPOJO Eclipse
Plug-in">Eclipse Plugin</a></li>
   <li><a href="/confluence/display/FELIX/iPOJO+Maven+Plug-in" title="iPOJO Maven
Plug-in">Maven Plugin</a></li>
   <li><a href="/confluence/display/FELIX/iPOJO-Arch-Command" title="iPOJO-Arch-Command"><tt>arch</tt>
shell command</a></li>
   <li><a href="/confluence/display/FELIX/apache-felix-ipojo-online-manipulator"
title="apache-felix-ipojo-online-manipulator">Online Manipulator</a></li>
   <li><a href="/confluence/display/FELIX/iPOJO+Webconsole+Plugin" title="iPOJO Webconsole
Plugin">Webconsole plugin</a></li>
   <li><a href="/confluence/display/FELIX/apache-felix-ipojo-junit4osgi" title="apache-felix-ipojo-junit4osgi">Junit4OSGi</a></li>
</ul>   
</li><!-- End of tools -->	
<!-- Menu 5 : Support -->
<li>
<a href="/confluence/display/FELIX/ipojo-support" title="ipojo-support">Support </a>
</li>
<!-- End of the menu 5 -->			
<!-- Menu 6 : Misc -->
<li class="">
<a href="#" class="sf-with-ul">Misc<span class="sf-sub-indicator"> »</span><span
class="sf-sub-indicator"> »</span></a>
<ul>
   <li><a href="/confluence/display/FELIX/apache-felix-ipojo-supportedVMs" title="apache-felix-ipojo-supportedVMs">Supported
JVMs</a></li>
   <li><a href="/confluence/display/FELIX/apache-felix-ipojo-supportedOSGi" title="apache-felix-ipojo-supportedOSGi">Supported
OSGi Implementations</a></li>
   <li><a href="http://ipojo-dark-side.blogspot.com" class="external-link" rel="nofollow">iPOJO's
Dark Side Blog</a></li>
   <li><a href="/confluence/pages/viewpage.action?pageId=54954" title="Article &amp;
Presentations">Article &amp; Presentations</a></li>
   <li><a href="http://www.apache.org/">ASF</a></li>
   <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
   <li><a href="http://www.apache.org/foundation/thanks.html">Sponsors</a></li>
</ul>
</li><!-- End of misc -->
</ul> <!-- End of the menu -->
</div> <!-- Page header -->
</p>

<div class="content">

<h1><a name="ProvidingOSGiservices-ProvidingOSGiservices"></a>Providing
OSGi services</h1>

<p><em>This handler allows publishing and providing OSGi services. It manages:</em></p>
<ul>
	<li><em>service publication</em></li>
	<li><em>service properties publication and management</em></li>
	<li><em>service object creation and creation strategies</em></li>
	<li><em>service un-registration</em></li>
	<li><em>configuration property propagation</em></li>
	<li><em>the management of the exposition from the implementation class</em></li>
</ul>


<div class="toc"><div>
<ul>
    <li><a href='#ProvidingOSGiservices-Asimpleexample'>A simple example</a></li>
    <li><a href='#ProvidingOSGiservices-ServicePublication'>Service Publication</a></li>
    <li><a href='#ProvidingOSGiservices-ServiceProperties'>Service Properties</a></li>
    <li><a href='#ProvidingOSGiservices-Advancedfeatures'>Advanced features</a></li>
<ul>
    <li><a href='#ProvidingOSGiservices-ServiceServing%26ObjectCreation'>Service
Serving &amp; Object Creation</a></li>
    <li><a href='#ProvidingOSGiservices-SeveralServiceProviding'>Several Service
Providing</a></li>
    <li><a href='#ProvidingOSGiservices-ServicePropertyPropagation'>Service Property
Propagation</a></li>
    <li><a href='#ProvidingOSGiservices-Instancereconfiguration'>Instance reconfiguration</a></li>
    <li><a href='#ProvidingOSGiservices-Publishingabstractandconcreteclassasservices'>Publishing
abstract and concrete class as services</a></li>
    <li><a href='#ProvidingOSGiservices-Controllingtheserviceexpositionfromtheimplementationclass'>Controlling
the service exposition from the implementation class</a></li>
    <li><a href='#ProvidingOSGiservices-Beingnotifiedoftheserviceregistrationandunregistration%28newinthe1.7.0SNAPSHOT%29'>Being
notified of the service registration and unregistration (new in the 1.7.0-SNAPSHOT)</a></li>
</ul>
</ul></div></div>

<h2><a name="ProvidingOSGiservices-Asimpleexample"></a>A simple example</h2>

<p>The following code snippet shows a simple class implementing the FooService interface:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class FooProviderType1 <span class="code-keyword">implements</span>
FooService {
            <span class="code-keyword">private</span> <span class="code-object">String</span>
m_foo = <span class="code-quote">"foo"</span>;

            <span class="code-keyword">public</span> void foo() {
                        <span class="code-object">System</span>.out.println(<span
class="code-quote">"foo  "</span> + m_foo);
            }

}
</pre>
</div></div>
<p>To provide a service, the implementation class <b>NEEDS</b> to implement
the service interface. By the way, it guaranties that each methods of the service interface
are implemented.</p>

<p>To provide the service, the component type needs to declare the providing:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component className=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
        <span class="code-tag">&lt;provides/&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foo.png?version=1&amp;modificationDate=1175853692000"
style="border: 0px solid black" /></span></p>

<p>The &lt;provides/&gt; element suffice to declare that each instance of this
type will provide the FooService. Indeed, the provided specification can be discovered by
analyzing the implementation class. By default, all implemented interface are published in
the same service registration. iPOJO looks down the entire inheritance tree.</p>

<h2><a name="ProvidingOSGiservices-ServicePublication"></a>Service Publication</h2>

<p>The provided service handler manages the service publication and providing. For each
declared <tt>provides</tt>, the handler register a service. The service is published
as long as the instance is valid. If the instance becomes invalid, the service is removed
from the service registry.</p>

<p>By default, it publishes all interfaces implemented by the implementation class of
the component class. It collects all super-interfaces (interfaces implemented by implemented
interfaces and by the super class). However it is possible to set exposed specifications with
the <tt>specifications</tt> attribute to avoid to expose all collected interfaces.</p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Change in
the 1.2.0</b><br />In the 1.0.0 version, the <tt>specifications</tt>
attribute was named <tt>interface</tt>.</td></tr></table></div>

<p>The following xml snippet is equivalent to the previous example:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
            <span class="code-tag">&lt;provides specifications=<span class="code-quote">"...FooService
"</span>/&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p>If the implementation class implements several interfaces, all these interfaces are
published by default in the same service publication. You can use the <tt>specifications</tt>
attribute to set published service interfaces. If you want to publish several interfaces,
you can use the following syntax:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
            <span class="code-tag">&lt;provides specifications=<span class="code-quote">"{...FooService,
...BarService}"</span>/&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foobar.png?version=1&amp;modificationDate=1175853692000"
style="border: 0px solid black" /></span></p>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>Specification
checking</b><br />If you use the <tt>specifications</tt> attribute,
the handler checks that all declared interfaces are really implemented by the implementation
class. If an interface is not implemented, the handler log a warning.</td></tr></table></div>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><b>No service</b><br
/>If the implementation class does not implement any interface, you cannot provide a service.
In this case, the handler throws an error.</td></tr></table></div>

<h2><a name="ProvidingOSGiservices-ServiceProperties"></a>Service Properties</h2>

<p>The handler can manage service properties. Service properties are attached to published
service and allow consumer filtering providers. A property can be attached to a field (contained
in the component implementation class), and so by handle dynamically.</p>

<p>Let's take a new example very closed of the last one:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class FooProviderType1 <span class="code-keyword">implements</span>
FooService {
	<span class="code-keyword">private</span> <span class="code-object">String</span>
m_foo;
	<span class="code-keyword">public</span> void foo() {
		<span class="code-object">System</span>.out.println(<span class="code-quote">"foo
 "</span> + m_foo);
                m_foo = <span class="code-quote">"bar"</span>;
	}
}
</pre>
</div></div>
<p>Remark that the <tt>m_foo</tt> field does not have any value. The following
snippet shows a component publishing the <tt>FooService</tt> with two properties:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
            <span class="code-tag">&lt;provides&gt;</span>
                        <span class="code-tag">&lt;property name=<span class="code-quote">"foo"</span>
field=<span class="code-quote">"m_foo"</span> value=<span class="code-quote">"Foo"</span>/&gt;</span>
                        <span class="code-tag">&lt;property name=<span class="code-quote">"intProps"</span>
type=<span class="code-quote">"int"</span> value=<span class="code-quote">"5"</span>/&gt;</span>
            <span class="code-tag">&lt;/provides&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p>The first declared property will be attached to the <tt>m_foo</tt> field.
This property is published with the name <tt>foo</tt>. This property has a default
value "Foo". This value will be injected in the <tt>m_foo</tt> field, when this
field asks for a value. A property with a field attribute does not need to declare a type
(the type can be discovered by analyzing the implementation class).</p>

<p>The second property is published with the name <tt>intProps</tt>. This
property is not attached to a field, so, we need to declare the property type. All primitive
types or objects can be used has property type (for object, the qualified name of the class
is used as java.lang.String).</p>

<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foo2.png?version=1&amp;modificationDate=1175853692000"
style="border: 0px solid black" /></span></p>

<p>The implementation class set a new value to the <tt>m_foo</tt> field
in the code. When this action occurs, the handler will modify the service publication to update
the <tt>foo</tt> property published value. If a published property value becomes
<tt>null</tt>, the property is unpublished since it has a new value.</p>

<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foo3.png?version=1&amp;modificationDate=1175853692000"
style="border: 0px solid black" /></span></p>

<p>If property does not have default value, the instance configuration needs to set
a value for each unvalued property. Moreover, the instance can override the property value.
The following xml snippet shows the declaration of an instance overriding the property values:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;instance component=<span class="code-quote">"...FooProviderType1"</span>
name=<span class="code-quote">"myFooServiceProvider"</span>&gt;</span>
            <span class="code-tag">&lt;property name=<span class="code-quote">"foo"</span>
value=<span class="code-quote">"baz"</span>/&gt;</span>
            <span class="code-tag">&lt;property name=<span class="code-quote">"intProps"</span>
value=<span class="code-quote">"2"</span>/&gt;</span>
<span class="code-tag">&lt;/instance&gt;</span>
</pre>
</div></div>
<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foo4.png?version=1&amp;modificationDate=1175853718000"
style="border: 0px solid black" /></span></p>

<h2><a name="ProvidingOSGiservices-Advancedfeatures"></a>Advanced features</h2>

<h3><a name="ProvidingOSGiservices-ServiceServing%26ObjectCreation"></a>Service
Serving &amp; Object Creation</h3>

<p>When a consumer requires the published service, the handler sends an object (instance)
of the implementation class. By default, it is always the same instance. If no instance already
exists, an instance is created.</p>

<p>However, the handler supports the OSGi <em>Service Factory</em>. In this
case, for each requester bundle, the handler sends a new object. To activate this policy,
add the <tt>strategy</tt> attribute in the <tt>provides</tt> element:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;provides strategy=<span class="code-quote">"SERVICE"</span>/&gt;</span>
</pre>
</div></div>

<p>Other strategies are available:</p>
<ul>
	<li><tt>strategy="instance"</tt> allows creating one service object per
asking iPOJO instance (despite they are in the same bundle)</li>
	<li>it is possible to create your own creation strategy by extending the <tt>org.apache.felix.ipojo.handlers.providedservice.CreationStrategy</tt>
class and by indicating the qualified class name in the <tt>strategy</tt> attribute.</li>
</ul>


<h3><a name="ProvidingOSGiservices-SeveralServiceProviding"></a>Several
Service Providing</h3>

<p>You can declare several <tt>provides</tt> inside the same component.
All this provided service will be manage by the same handler but separately. Several services
will be published (with different service registrations). This case is useful when service
properties are different for the different services.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
                <span class="code-tag">&lt;provides specifications=<span class="code-quote">"...Foo"</span>/&gt;</span>
                <span class="code-tag">&lt;provides specifications=<span class="code-quote">"...Bar"</span>&gt;</span>
                               <span class="code-tag">&lt;property name=<span
class="code-quote">"foo"</span> value=<span class="code-quote">"baz"</span>/&gt;</span>
                <span class="code-tag">&lt;/provides&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-foobar2.png?version=1&amp;modificationDate=1175853718000"
style="border: 0px solid black" /></span></p>

<h3><a name="ProvidingOSGiservices-ServicePropertyPropagation"></a>Service
Property Propagation</h3>

<p>The configuration handler has the possibility to propagate received properties to
service publication. So, when the propagation is activated (on the <tt>properties</tt>
elelmenet or on the <tt>@Component</tt> annotation), all properties received by
the configuration handler will be propagated to all published service. If some properties
are mapped on methods, these methods are invoked with the new value in argument.</p>

<p><span class="image-wrap" style=""><img src="/confluence/download/attachments/27614/ps-propagation.png?version=1&amp;modificationDate=1175853718000"
style="border: 0px solid black" /></span></p>

<p>If an instance configuration contains properties starting with <tt>service.</tt>,
they are automatically propagated. In the following example, the <tt>service.pid</tt>
is automatically propagated.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;instance component=<span class="code-quote">"..."</span>&gt;</span>
    <span class="code-tag">&lt;property name=<span class="code-quote">"service.pid"</span>
value=<span class="code-quote">"my.pid"</span>/&gt;</span>
<span class="code-tag">&lt;/instance&gt;</span>
</pre>
</div></div>

<h3><a name="ProvidingOSGiservices-Instancereconfiguration"></a>Instance
reconfiguration</h3>

<p>The handler supports instance reconfiguration. When an instance is dynamically reconfigured,
if the new configuration updates property values, these value are take into account (both
for field, and service publication). If some of these properties have methods, these methods
are invoked with the new value in argument.</p>

<h3><a name="ProvidingOSGiservices-Publishingabstractandconcreteclassasservices"></a>Publishing
abstract and concrete class as services</h3>

<p>It is also possible to expose concrete and abstract class as services. To to this,
just specify the published class in the <tt>specification</tt> attribute:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooProviderType1"</span>&gt;</span>
                <span class="code-tag">&lt;provides specifications=<span class="code-quote">"...AbstractFoo"</span>/&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
<span class="code-tag">&lt;component classname=<span class="code-quote">"...FooBarProviderType1"</span>&gt;</span>
                <span class="code-tag">&lt;provides specifications=<span class="code-quote">"[...AbstractFoo,
...Bar]"</span>/&gt;</span>
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>
<p>The component can also publish itself as a service. However, such practice are not
recommended.</p>

<h3><a name="ProvidingOSGiservices-Controllingtheserviceexpositionfromtheimplementationclass"></a>Controlling
the service exposition from the implementation class</h3>

<p>This handler also allows the injection of a 'service controller'. The injected boolean
field allows the code to impact the service publication. Setting the field to <tt>false</tt>
unregisters the service from the service registry. Setting it back to <tt>true</tt>
re-publishes the service.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class ControllerCheckService <span
class="code-keyword">implements</span> FooService, CheckService {
    
    
    <span class="code-keyword">private</span> <span class="code-object">boolean</span>
controller; <span class="code-comment">// Service Controller
</span>
    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
foo() {
        <span class="code-keyword">return</span> controller;
    }

    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
check() {
        <span class="code-object">System</span>.out.println(<span class="code-quote">"Before
: "</span> + controller);
        controller = ! controller; <span class="code-comment">// Change the publication
</span>        <span class="code-object">System</span>.out.println(<span
class="code-quote">"After : "</span> + controller);
        <span class="code-keyword">return</span> controller;
    }

}
</pre>
</div></div>

<p>For the previous component, the metadata may be :</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  &lt;component classname=<span class="code-quote">"org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"</span>
    name=<span class="code-quote">"PS-Controller-1-default"</span>&gt;
    <span class="code-tag">&lt;provides&gt;</span>
      <span class="code-tag">&lt;controller field=<span class="code-quote">"controller"</span>/&gt;</span>
    <span class="code-tag">&lt;/provides&gt;</span>
  <span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>

<p>Each <tt>provides</tt> can have one <tt>controller</tt> element.
The <tt>controller</tt> element must have a field attribute and may have a value
attribute setting the initial value. Setting this value to false disables the initial service
registration:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  &lt;component classname=<span class="code-quote">"org.apache.felix.ipojo.test.scenarios.component.controller.ControllerCheckService"</span>
    name=<span class="code-quote">"PS-Controller-1-false"</span>&gt;
    <span class="code-tag">&lt;provides&gt;</span>
      <span class="code-tag">&lt;controller field=<span class="code-quote">"controller"</span>
value=<span class="code-quote">"false"</span>/&gt;</span>
    <span class="code-tag">&lt;/provides&gt;</span>
  <span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>

<p>If you're using annotations, the <tt>@ServiceController</tt> annotation
creates a service controller. However, you can have only one service controller per class.
</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Component
@Provides
<span class="code-keyword">public</span> class PSServiceController <span class="code-keyword">implements</span>
FooService, BarService {

    @ServiceController(value=<span class="code-keyword">false</span>)
    <span class="code-keyword">public</span> <span class="code-object">boolean</span>
controller;
  
    <span class="code-comment">// ...</span>
</pre>
</div></div>

<h3><a name="ProvidingOSGiservices-Beingnotifiedoftheserviceregistrationandunregistration%28newinthe1.7.0SNAPSHOT%29"></a>Being
notified of the service registration and unregistration (new in the 1.7.0-SNAPSHOT)</h3>
<p>This handler also proposed a way to the implementation class to be notified when
the services a published and unpublished.This is done byu specifying the two callback in the
<tt>&lt;provides/&gt;</tt> element:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
&lt;component
     classname=<span class="code-quote">"org.apache.felix.ipojo.test.scenarios.component.callbacks.CallbacksCheckService"</span>
     name=<span class="code-quote">"PS-Callbacks-both-1"</span>&gt;
    &lt;provides
	specifications=<span class="code-quote">"org.apache.felix.ipojo.test.scenarios.ps.service.FooService"</span>
	post-unregistration=<span class="code-quote">"unregistered"</span> post-registration=<span
class="code-quote">"registered"</span>/&gt;
    &lt;provides
	specifications=<span class="code-quote">"org.apache.felix.ipojo.test.scenarios.ps.service.CheckService"</span>
	post-unregistration=<span class="code-quote">"unregistered"</span> post-registration=<span
class="code-quote">"registered"</span>/&gt;
<span class="code-tag">&lt;/component&gt;</span>
</pre>
</div></div>

<p>Each <tt>provides</tt> element can specify:</p>
<ul>
	<li>a <tt>post-registration</tt> callback : called after the service publication</li>
	<li>a <tt>post-unregistration</tt> callback : called after the service
unpublication</li>
</ul>


<p>Those attributes specify the method name to call. Those method must have the following
signature: <tt>public void name(ServiceReference ref)</tt>. So they receive the
published / unpublished service reference. The callbacks are called in the same thread as
the publication / unpublication itself. </p>

<p>It is also possible to use annotations to specify such callbacks:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
	@PostRegistration
	<span class="code-keyword">public</span> void registered(ServiceReference ref)
{
		<span class="code-object">System</span>.out.println(<span class="code-quote">"Registered"</span>);
	}

        @PostUnregistration
	<span class="code-keyword">public</span> void unregistered(ServiceReference ref)
{
		<span class="code-object">System</span>.out.println(<span class="code-quote">"Unregistered"</span>);
	}
</pre>
</div></div>
<p><br class="atl-forced-newline" />
<br class="atl-forced-newline" /></p>

 </div>
        <img src="http://felix.apache.org/ipojo/site/footer.png" class="footer">
</div>

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-1518442-4");
pageTracker._trackPageview();
} catch(err) {}
</script>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="http://cwiki.apache.org/confluence/display/FELIX/Providing+OSGi+services">View
Online</a>
        |
        <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27614&revisedVersion=30&originalVersion=29">View
Changes</a>
                |
        <a href="http://cwiki.apache.org/confluence/display/FELIX/Providing+OSGi+services?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message