You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by bu...@apache.org on 2018/10/09 23:09:56 UTC

svn commit: r1036215 - in /websites/staging/felix/trunk/content: ./ documentation/subprojects/apache-felix-dependency-manager/reference/service-scopes.html

Author: buildbot
Date: Tue Oct  9 23:09:56 2018
New Revision: 1036215

Log:
Staging update by buildbot for felix

Added:
    websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/service-scopes.html
Modified:
    websites/staging/felix/trunk/content/   (props changed)

Propchange: websites/staging/felix/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Tue Oct  9 23:09:56 2018
@@ -1 +1 @@
-1843304
+1843364

Added: websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/service-scopes.html
==============================================================================
--- websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/service-scopes.html (added)
+++ websites/staging/felix/trunk/content/documentation/subprojects/apache-felix-dependency-manager/reference/service-scopes.html Tue Oct  9 23:09:56 2018
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE- 2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+  <head>
+    <title>Apache Felix - </title>
+    <link rel="icon" href="/res/favicon.ico">
+    <link rel="stylesheet" href="/res/site.css" type="text/css" media="all">
+    <link rel="stylesheet" href="/res/codehilite.css" type="text/css" media="all">
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+  </head>
+  <body>
+    <div class="title">
+      <div class="logo">
+        <a href="http://felix.apache.org/">
+          <img border="0" alt="Apache Felix" src="/res/logo.png">
+        </a>
+      </div>
+      <div class="header">
+        <a href="http://www.apache.org/">
+          <img border="0" alt="Apache" src="/res/apache.png">
+        </a>
+      </div>
+    </div>
+    
+    <div class="menu"> 
+      <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<p><a href="/news.html">News</a>  <br />
+<a href="/license.html">License</a>  <br />
+<a href="/downloads.cgi">Downloads</a>  <br />
+<a href="/documentation.html">Documentation</a>  <br />
+<a href="/mailinglists.html">Mailing Lists</a>  <br />
+<a href="/documentation/community/contributing.html">Contributing</a>  <br />
+<a href="/sitemap.html">Site Map</a>  <br />
+<a href="http://www.apache.org/">ASF</a>  <br />
+<a href="http://www.apache.org/security/">Security</a>  <br />
+<a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a>  <br />
+<a href="http://www.apache.org/foundation/thanks.html">Sponsors</a>    </p>
+<iframe
+    src="http://www.apache.org/ads/button.html"
+    style="border-width:0; float: left"
+    frameborder="0"
+    scrolling="no"
+    width="135"
+    height="135">
+</iframe>
+    </div>
+    
+    <div class="main">
+      <div class="breadcrump" style="font-size: 80%;">
+        <a href="/">Home</a>&nbsp;&raquo&nbsp;<a href="/documentation.html">Documentation</a>&nbsp;&raquo&nbsp;<a href="/documentation/subprojects.html">Apache Felix Subproject Documentation</a>&nbsp;&raquo&nbsp;<a href="/documentation/subprojects/apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a>
+      </div>
+
+      <h1></h1>
+      <style type="text/css">
+/* The following code is added by mdx_elementid.py
+   It was originally lifted from http://subversion.apache.org/style/site.css */
+/*
+ * Hide class="elementid-permalink", except when an enclosing heading
+ * has the :hover property.
+ */
+.headerlink, .elementid-permalink {
+  visibility: hidden;
+}
+h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink, h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink, dt:hover > .elementid-permalink { visibility: visible }</style>
+<p>Title: Dependency Manager - Service Scopes</p>
+<p>By default service providers are registered once in the osgi registry, and all service consumers share the same service provider instance.
+Now, you can control the scope of the provided services: From the provider side, a "scope" parameter 
+is available for all types of DM components and allows to define the scope of the registered service.</p>
+<p>The <code>scope</code> attribute has three enum values: SINGLETON, BUNDLE, PROTOTYPE</p>
+<ul>
+<li>SINGLETON: it's as before: your registered service is a singleton, meaning that the service must be 
+instantiated and registered once, and all using services will share the same service instance of your component.</li>
+<li>BUNDLE: the service will be registered as a ServiceFactory, meaning an instance of the component must be 
+created for each bundle using the service.</li>
+<li>PROTOTYPE: the service will be registered as a PrototypeServiceFactory, meaning the service is registered as 
+a prototype scope service and an instance of the component must be created for each distinct service requester.</li>
+</ul>
+<p>Scoped Services are supported by all kind of DM service components:</p>
+<ul>
+<li>Component</li>
+<li>Aspects</li>
+<li>Adapters</li>
+<li>Bundle Adapters</li>
+<li>Resource Adapters</li>
+</ul>
+<p>When a consumer requests a service (using ServiceDependency), then DM will automatically 
+dereference the service like this:</p>
+<ul>
+<li>if the service has a SERVICE_SCOPE service property matching SCOPE_PROTOTYPE, the DM will 
+internally derefence the service using the ServiceObject API: so, the consumer will get its own copy 
+of the requested service instance.</li>
+<li>else, DM will internally dereference the service, as before.
+When defining scoped component implementation, you can optionally define two special class fields 
+in order to get injected with the client Bundle requesting the service, and the ServiceRegisgtration 
+Object. Just use @Inject annotations in order to get injected with the client 
+Bundle or the ServiceRegistration. You can also define a constructor which takes as argument the 
+client bundle as well as the service registration.</li>
+</ul>
+<h1 id="examples">Examples<a class="headerlink" href="#examples" title="Permanent link">&para;</a></h1>
+<p>So, here is a MyService component with PROTOTYPE scope, and each requester will get its own copy 
+of MyService instance (the MyServiceImpl.start() method will be called for each MyServiceImpl 
+instance):</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Activator</span> <span class="kd">extends</span> <span class="n">DependencyActivatorBase</span> <span class="o">{</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="o">,</span> <span class="n">DependencyManager</span> <span class="n">dm</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
+        <span class="n">dm</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">createComponent</span><span class="o">()</span>
+            <span class="o">.</span><span class="na">setScope</span><span class="o">(</span><span class="n">ServiceScope</span><span class="o">.</span><span class="na">PROTOTYPE</span><span class="o">)</span>
+            <span class="o">.</span><span class="na">setInterface</span><span class="o">(</span><span class="n">MyService</span><span class="o">.</span><span class="na">class</span><span class="o">.</span><span class="na">getName</span><span class="o">(),</span> <span class="kc">null</span><span class="o">)</span>
+            <span class="o">.</span><span class="na">setImplementation</span><span class="o">(</span><span class="n">MyServiceImpl</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyServiceImpl</span> <span class="kd">implements</span> <span class="n">MyService</span> <span class="o">{</span>
+    <span class="kt">void</span> <span class="nf">start</span><span class="o">()</span> <span class="o">{</span>
+        <span class="c1">// called on each MyService instance</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>The MyServiceImpl, like with annotations, can define a constructor in order to be injected with 
+the client bundle invoking the service and also the service Registration:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyServiceImpl</span> <span class="kd">implements</span> <span class="n">MyService</span> <span class="o">{</span>
+    <span class="kd">public</span> <span class="nf">MyServiceImpl</span><span class="o">(</span><span class="n">Bundle</span> <span class="n">clientBundle</span><span class="o">,</span> <span class="n">ServiceRegistration</span> <span class="n">reg</span><span class="o">)</span> <span class="o">{</span> <span class="o">...</span> <span class="o">}</span>
+    <span class="kt">void</span> <span class="nf">start</span><span class="o">()</span> <span class="o">{</span>
+        <span class="c1">// called on each MyService instance</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>(if you want to auto configure the client Bundle, and the ServiceRegistration, then simply define class fields, they will be auto injected, unless you disable auto configuraiton for Bundle/ServiceRegistration using Component.setAutoConfig(Class, boolean) methods.</p>
+<p>Here is a Client component which simply depends on the MyService service using a basic DM 
+activator (nothing special to do):</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Activator</span> <span class="kd">extends</span> <span class="n">DependencyActivatorBase</span> <span class="o">{</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="o">,</span> <span class="n">DependencyManager</span> <span class="n">dm</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
+        <span class="n">dm</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">createComponent</span><span class="o">()</span>
+            <span class="o">.</span><span class="na">setImplementation</span><span class="o">(</span><span class="n">Client</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+            <span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">createServiceDependency</span><span class="o">()</span>
+                 <span class="o">.</span><span class="na">setService</span><span class="o">(</span><span class="n">MyService</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="kc">null</span><span class="o">).</span><span class="na">setRequired</span><span class="o">(</span><span class="kc">true</span><span class="o">).</span><span class="na">setCallbacks</span><span class="o">(</span><span class="s">&quot;bind&quot;</span><span class="o">,</span> <span class="s">&quot;unbind&quot;</span><span class="o">));</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Client</span> <span class="o">{</span>
+    <span class="kt">void</span> <span class="nf">bind</span><span class="o">(</span><span class="n">MyService</span> <span class="n">service</span><span class="o">)</span> <span class="o">{</span>
+        <span class="c1">// our client is injected with a specific instance of the MyService component </span>
+        <span class="c1">// that is created for our Client.</span>
+        <span class="c1">// If another component defines a service dependency on MyService, then the other </span>
+        <span class="c1">// component will get its own private copy of MyService component instance</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h1 id="example-using-serviceobjects-api">Example using ServiceObjects API<a class="headerlink" href="#example-using-serviceobjects-api" title="Permanent link">&para;</a></h1>
+<p>If now you want to control the creation of the MyService using raw OSGI ServiceObjects API, 
+you can also do it like this:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Client</span> <span class="o">{</span>
+    <span class="kt">void</span> <span class="nf">bind</span><span class="o">(</span><span class="n">ServiceObjects</span><span class="o">&lt;</span><span class="n">MyService</span><span class="o">&gt;</span> <span class="n">so</span><span class="o">)</span> <span class="o">{</span>
+        <span class="n">MyService</span> <span class="n">s1</span> <span class="o">=</span> <span class="n">so</span><span class="o">.</span><span class="na">getService</span><span class="o">();</span>
+        <span class="n">MyService</span> <span class="n">s2</span> <span class="o">=</span> <span class="n">so</span><span class="o">.</span><span class="na">getService</span><span class="o">();</span>
+        <span class="o">...</span>
+        <span class="n">so</span><span class="o">.</span><span class="na">ungetService</span><span class="o">(</span><span class="n">s1</span><span class="o">);</span> <span class="c1">// will deactivate the MyService s1 instance</span>
+        <span class="n">so</span><span class="o">.</span><span class="na">ungetService</span><span class="o">(</span><span class="n">s2</span><span class="o">);</span> <span class="c1">// will deactivate the MyService s2 instance</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h1 id="scoped-services-and-initdestroy-callbacks">Scoped services and init/destroy callbacks<a class="headerlink" href="#scoped-services-and-initdestroy-callbacks" title="Permanent link">&para;</a></h1>
+<p>When you need to specify dynamic dependencies from your component.init() method, 
+the following mechanism will be used:</p>
+<p>first, if your component defines an init callback, then one single component prototype instance singleton is created, as if the component is declared with SCOPE=SINGLETON.
+so, the prototype instance will be invoked in the init callback, but won't be started or stopped
+and when all dependencies are satisfied (including the dynamic dependencies), 
+then the ServiceFactory (or PrototypeServiceFactory) is registered.
+And when one client will request a component instance, then a clone will be created and returned.</p>
+<p>Example of a scoped component which defines an init method:</p>
+<div class="codehilite"><pre><span class="kn">import</span> <span class="nn">org.apache.felix.dm.annotation.api.Component</span><span class="o">;</span>
+<span class="kn">import</span> <span class="nn">org.apache.felix.dm.annotation.api.ServiceScope</span><span class="o">;</span>
+
+<span class="nd">@Component</span><span class="o">(</span><span class="n">scope</span><span class="o">=</span><span class="n">ServiceScope</span><span class="o">.</span><span class="na">PROTOTYPE</span><span class="o">)</span>
+<span class="kd">public</span> <span class="kd">static</span> <span class="kd">class</span> <span class="nc">MyServiceImpl</span> <span class="kd">implements</span> <span class="n">MyService</span> <span class="o">{</span>
+
+   <span class="nd">@Init</span>
+   <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">Component</span> <span class="n">comp</span><span class="o">)</span> <span class="o">{</span>
+        <span class="c1">// add dependencies dynamically</span>
+   <span class="o">}</span>
+
+    <span class="nd">@Start</span>
+    <span class="kt">void</span> <span class="nf">start</span><span class="o">()</span> <span class="o">{</span>
+       <span class="c1">// only called on clones, not on the prototype instance</span>
+    <span class="o">}</span>
+
+    <span class="nd">@Stop</span>
+    <span class="kt">void</span> <span class="nf">stop</span><span class="o">()</span> <span class="o">{</span>
+       <span class="c1">// called on each clone, not on the prototype instance singleton</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<h1 id="limitation-when-using-dm-servicedependency-from-api-and-serviceobjects">Limitation when using DM ServiceDependency from API and ServiceObjects<a class="headerlink" href="#limitation-when-using-dm-servicedependency-from-api-and-serviceobjects" title="Permanent link">&para;</a></h1>
+<p>When using DependencyManager ServiceDependency from the native API (not using annotations), 
+you have to know that the ServiceDependency always internally dereferences and creates the 
+scoped service, even if you specify a ServiceObjecs 
+parameter in your bind method. If now you really want to disable the auto-deref ServiceDependency 
+(because you want to directly use the ServiceObjects API), you must then use the 
+"setDereference(false") method on your ServiceDependency: in this way, you tell DM to never 
+dereference internally the scoped service. Here is an example:</p>
+<div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Activator</span> <span class="kd">extends</span> <span class="n">DependencyActivatorBase</span> <span class="o">{</span>
+    <span class="nd">@Override</span>
+    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">init</span><span class="o">(</span><span class="n">BundleContext</span> <span class="n">context</span><span class="o">,</span> <span class="n">DependencyManager</span> <span class="n">dm</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span>
+        <span class="n">dm</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">createComponent</span><span class="o">()</span>
+            <span class="o">.</span><span class="na">setImplementation</span><span class="o">(</span><span class="n">Client</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
+            <span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">createServiceDependency</span><span class="o">()</span>
+                 <span class="o">.</span><span class="na">setService</span><span class="o">(</span><span class="n">MyService</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="kc">null</span><span class="o">).</span><span class="na">setRequired</span><span class="o">(</span><span class="kc">true</span><span class="o">).</span><span class="na">setCallbacks</span><span class="o">(</span><span class="s">&quot;bind&quot;</span><span class="o">,</span> <span class="s">&quot;unbind&quot;</span><span class="o">)</span>
+                 <span class="o">.</span><span class="na">setDereference</span><span class="o">(</span><span class="kc">false</span><span class="o">));</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+
+<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Client</span> <span class="o">{</span>
+    <span class="kt">void</span> <span class="nf">bind</span><span class="o">(</span><span class="n">ServiceObjects</span><span class="o">&lt;</span><span class="n">MyService</span><span class="o">&gt;</span> <span class="n">so</span><span class="o">)</span> <span class="o">{</span>
+        <span class="n">MyService</span> <span class="n">s1</span> <span class="o">=</span> <span class="n">so</span><span class="o">.</span><span class="na">getService</span><span class="o">();</span>
+        <span class="n">MyService</span> <span class="n">s2</span> <span class="o">=</span> <span class="n">so</span><span class="o">.</span><span class="na">getService</span><span class="o">();</span>
+        <span class="o">...</span>
+        <span class="n">so</span><span class="o">.</span><span class="na">ungetService</span><span class="o">(</span><span class="n">s1</span><span class="o">);</span> <span class="c1">// will deactivate the MyService s1 instance</span>
+        <span class="n">so</span><span class="o">.</span><span class="na">ungetService</span><span class="o">(</span><span class="n">s2</span><span class="o">);</span> <span class="c1">// will deactivate the MyService s2 instance</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</pre></div>
+
+
+<p>In the above example, the Activator defines the ServiceDependency using the 
+ServiceDependency.setDereference(false) method because it's the Client.bind method which will 
+create the MyService instances manually.</p>
+<p>In the future, I will try to auto detect the signatures of the Client.bind method in order to 
+never auto-dereference the injected service in case the bind method takes as argument a 
+ServiceObjects (or a ServiceReference) method.</p>
+      <div class="timestamp" style="margin-top: 30px; font-size: 80%; text-align: right;">
+        Rev. 1843364 by pderop on Tue, 9 Oct 2018 23:09:14 +0000
+      </div>
+      <div class="trademarkFooter"> 
+        Apache Felix, Felix, Apache, the Apache feather logo, and the Apache Felix project
+        logo are trademarks of The Apache Software Foundation. All other marks mentioned
+        may be trademarks or registered trademarks of their respective owners.
+      </div>
+    </div>
+  </body>
+</html>