blob: 7cf1e51b9b93573da307c5153ec7ff4c26fe659d [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="compendium" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Compendium Services</title>
<para>The OSGi Service Platform Service Compendium specification defines a
number of additional services that may be supported by OSGi
implementations. Gemini Blueprint supports an additional
"compendium" namespace that provides integration with some of these services.
By convention, the prefix <literal>osgix</literal> is used for this
namespace:</para>
<programlistingco>
<areaspec>
<areaset id="compendium:ns:xml:uri.prefix" coords="">
<area id="compendium:ns:xml:uri.prefix.1" coords="4 93"/>
<area id="compendium:ns:xml:uri.prefix.2" coords="4 10"/>
</areaset>
<area id="compendium:ns:xml:uri" coords="8 95"/>
<area id="compendium:ns:xml:uri.loc" coords="9 95"/>
</areaspec>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">
<!-- use the OSGi namespace elements directly -->
<service id="simpleServiceOsgi" ref="simpleService"
interface="org.xyz.MyService" />
<!-- qualify compendium namespace elements -->
<compendium:cm-properties id="cm" persistent-id="com.xyz.myapp"/>
</beans:beans>]]></programlisting>
<calloutlist>
<callout arearefs="compendium:ns:xml:uri.prefix">
<para>Compendium namespace declaration (bound to <literal>osgix</literal> prefix)</para>
</callout>
<callout arearefs="compendium:ns:xml:uri">
<para>Schema location (namespace URI)</para>
</callout>
<callout arearefs="compendium:ns:xml:uri.loc">
<para>XML schema to use for the compendium namespace</para>
</callout>
</calloutlist>
</programlistingco>
<para>At present this namespace provides support for the Configuration
Admin service. Support for other compendium services may be added in
future releases.</para>
<section id="compendium:cm">
<title>Configuration Admin</title>
<para>One of the most important compendium services, is the <ulink url="http://www.osgi.org/javadoc/r4v401/org/osgi/service/cm/package-summary.html">Configuration Admin</ulink>
which, as a name implies, provides configuration to interested bundles through the OSGi service registry. Gemini Blueprint provides dedicated support
for Configuration Admin (CM), allowing consumption and injection of the configuration data in a declarative way.</para>
<section id="compendium:cm:props">
<title>Exposing Configuration Admin Entries As <classname>Properties</classname></title>
<para>In its simplest form, the CM can be seen as a configuration source, namely a <classname>Dictionary</classname> whose
keys are always <classname>String</classname>s. Gemini Blueprint can expose entries in the CM as a <classname>Properties</classname> object,
through the <literal>cm-properties</literal> element. A minimal declaration looks as follows:</para>
<programlisting language="xml"><![CDATA[<osgix:cm-properties id="ds.cfg" persistent-id="data.source.office.1"/>]]></programlisting>
<para>The configuration above, exposes the properties available in the CM under <emphasis>data.source.office.1</emphasis> entry as a bean named
<emphasis>ds.cfg</emphasis>.</para>
<note><para>The <literal>persistent-id</literal> attribute must refer to the
persistent-id of an OSGi <interfacename>ManagedService</interfacename>, it is a
configuration error to specify a factory persistent id referring to a
<interfacename>ManagedServiceFactory</interfacename>.</para></note>
<para>Those familiar with Spring's
<ulink url="http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/xsd-configuration.html#xsd-config-body-schemas-util">util schema</ulink> will
find <literal><![CDATA[<osgi:cm-properties/>]]></literal> element similar to <literal><![CDATA[<util:properties/>]]></literal>.</para>
<para>It is possible to specify a default set of property values to be used in the event that the configuration dictionary does not contain
an entry for a given key. The declaration is similar to the <literal>props</literal> element inside the Spring beans namespace:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">
<compendium:cm-properties id="cfg.with.defaults" persistent-id="data.source.office.2">
<beans:prop key="host">localhost</beans:prop>
<beans:prop key="port">3306</beans:prop>
</compendium:cm-properties>
</beans:beans>]]></programlisting>
<para>By default, the properties found in the Configuration Admin entry will override the local properties. Thus, for the previous example, if the
<literal>data.source.office.2</literal> configuration contains a <emphasis>host</emphasis> entry, its value will override the locally defined
<literal>localhost</literal>. For cases where this behaviour is undesired, the attribute <literal>local-override</literal>
(default <literal>false</literal>) allows one to revert the merging algorithm, forcing the local properties to override the entries in the CM.</para>
<para>Since <literal>cm-properties</literal> exposes the CM entries as <classname>Properties</classname>, it can be used with Spring's <classname>
<ulink url="http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/beans.html#beans-factory-placeholderconfigurer">PropertyPlaceholderConfigurer</ulink></classname>
and <classname><ulink url="http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/beans.html#beans-factory-overrideconfigurer">PropertyOverrideConfigurer</ulink></classname>
to externalize and customize environment-specific properties:</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:compendium="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd">
<!-- Configuration Admin entry -->
<compendium:cm-properties id="cmProps" persistent-id="com.xyz.myapp">
<prop key="host">localhost</prop>
</compendium:cm-properties>
<!-- placeholder configurer -->
<context:property-placeholder properties-ref="cmProps" />
<bean id="dataSource" ...>
<property name="host" value="${host}"/>
<property name="timeout" value="${timeout}"/>
</bean>
</beans>]]></programlisting>
<para>An important aspect of <literal>cm-properties</literal> is does <emphasis>not</emphasis> reflect
any that any subsequent changes made to the entry it represents, made through the Configuration Admin API.
That is, once resolved, the <literal>cm-properties</literal> content remains the same, regardless of any updates
made the to CM entry it represents.</para>
</section>
<section id="compendium:cm:managed-properties">
<title>Managed Properties</title>
<para>Based on a configuration admin entry, Gemini Blueprint can autowire by name, the properties of a given bean. To use this feature, define
a nested <literal>managed-properties</literal> inside the bean definition:</para>
<programlisting language="xml"><![CDATA[<bean id="managedComponent" class="MessageTank">
<osgix:managed-properties persistent-id="com.xyz.messageservice"/>
</bean>]]></programlisting>
<para>For each key in the dictionary stored by Configuration Admin under the given persistent id,
if the bean type has a property with a matching name (following JavaBeans conventions),
then that component property will be dependency injected with the value stored in Configuration Admin under the key.
If the definition of <classname>SomeClass</classname> from the example above is as follows:</para>
<programlisting language="java"><![CDATA[public class MessageTank {
private int amount;
public int getAmount() { return this.amount; }
public void setAmount(int amount) { this.amount = amount; }
}]]></programlisting>
<para>and the configuration dictionary stored under the pid <literal>com.xyz.messageservice</literal> contains an entry
<literal>amount=200</literal>, then the <literal>setAmount</literal> method will be invoked on the bean
instance during configuration, passing in the value <literal>200</literal>.</para>
<para>If a property value is defined both in the configuration dictionary stored in the Configuration Admin service and in a
property element declaration nested in the component element, then the value from Configuration Admin takes precedence:</para>
<programlisting language="xml"><![CDATA[<bean id="managedComponent" class="MessageTank">
<osgix:managed-properties persistent-id="com.xyz.messageservice"/>
<property name="amount" value="100"/>
<property name="threshold" value="500"/>
</bean>]]></programlisting>
<para>Property values specified via property elements can therefore be treated as default values to be used if none is available through
Configuration Admin.</para>
<warning>Do not share the same <emphasis>persistent-id</emphasis> (PID) between multiple bundles or definitions, as <emphasis>only one</emphasis>
of them will receive notifications. <literal>managed-properties</literal> relies on <literal>org.osgi.service.cm.ManagedService</literal>
contract which mandates that each <literal>ManagedService</literal> instance must be identified with its own unique PID.
Please see the Configuration Admin spec, specifically section 104.3 and 104.5</warning>
<section id="compendium:cm:managed-properties:update">
<title>Configuration Admin Runtime Updates</title>
<para>A powerful feature of Configuration Admin is the ability to update (or delete) entries at runtime. That is, the configuration data
stored in Configuration Admin may be updated after the bean has been created. By default, any post-creation updates will be ignored. However,
one can configure <literal>managed-properties</literal> element to receive configuration updates through the <literal>autowire-on-update</literal>
and <literal>update-method</literal> attributes.</para>
<para><literal>update-method</literal> specifies the bean method to invoke whenever an update occurs in the configuration data.
The update method must have one of the following signatures:</para>
<programlisting language="java"><![CDATA[public void anyMethodName(Map properties)
public void anyMethodName(Map<String,?> properties); // for Java 5]]></programlisting>
<para>If <literal>autowire-on-update</literal> is set to <literal>true</literal> (default is <literal>false</literal>) then the container will autowire the target bean everytime an update occurs.
If both <literal>autowire-on-update</literal> and <literal>update-method</literal> are specified then the autowiring process will take precedence.
For autowiring, the component class must provide setter methods for the component properties that it wishes to have updated. Consider the following class definitions:</para>
<programlisting language="java"><![CDATA[public class ContainerManagedBean {
// will be reinjected (since it has a setter)
private Integer integer;
// will not be reinjected (no setter present)
private Long waitTime;
public void setInteger(Integer integer) { this.integer = integer; }
}
public class SelfManagedBean {
// update callback
public void updateCallback(Map properties) {
System.out.println("Received properties " + properties);
System.out.println("Props can be used as a Dictionary " + (Dictionary) properties);
// do more work ...
}
}]]></programlisting>
<para>and configuraton:</para>
<programlisting language="xml"><![CDATA[<bean id="containerManaged" class="ContainerManagedBean">
<osgix:managed-properties persistent-id="labX" autowire-on-update="true"/>
<property name="integer" value="23"/>
</bean>
<bean id="beanManaged" class="SelfManagedBean">
<osgix:managed-properties persistent-id="labY" update-method="updateCallback"/>
</bean>]]></programlisting>
<para>Any updates made to the CM entry <literal>labX</literal> will be automatically reinjected on existing instances of
<literal>containerManaged</literal> bean while the <literal>labY</literal> updates will be passed to <methodname>updateCallback</methodname>
method.</para>
<para>The update options are summarized in the table below:</para>
<table id="compendium-cm-managed-properties-options" pgwide="1">
<title>Managed Properties Update Options</title>
<tgroup cols="3">
<colspec colname="c1" colwidth="2*"/>
<colspec colname="c2" colwidth="1*"/>
<colspec colname="c3" colwidth="4*"/>
<thead>
<row>
<entry><literal>autowire-on-update</literal></entry>
<entry><literal>update-method</literal></entry>
<entry>Behaviour</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>true</literal></entry>
<entry><emphasis>optional</emphasis>, called after autowiring</entry>
<entry>Reinjects the bean properties, using the properties present in the update. The re-injection will be applied while locking (through
a <literal>synchronized</literal> instruction) the bean instance. If the locking or re-injection strategy is not suitable, consider using
the <literal>update-method</literal> only approach.</entry>
</row>
<row>
<entry><literal>false</literal> (default)</entry>
<entry><emphasis>optional</emphasis></entry>
<entry>Invokes the <literal>update-method</literal> callback on the bean instance, passing the updated configuration (as a
<interfacename>Map</interfacename> object that can be safely cast to a <classname>Dictionary</classname> if needed). No locking is
performed.</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<section id="compendium:cm:managed-service-factories">
<title>Managed Service Factories</title>
<para>The Configuration Admin service supports a notion of a <emphasis>managed service factory</emphasis>(see section 104.6 in the Compendium Specification).
A managed service factory is identified by a factory pid which allows <emphasis>multiple</emphasis> <interfacename>Configuration</interfacename> objects
to be associated with the factory. <interfacename>Configuration</interfacename> objects associated with the factory can be added or removed at any point.
The main intent of a factory is to create an OSGi service for each configuration: adding a new <interfacename>Configuration</interfacename> entry results
in a new OSGi service being registered, removing a <interfacename>Configuration</interfacename>, unregisters the service.
Gemini Blueprint provides support for the <emphasis>managed service factory</emphasis> concept through the <literal>managed-service-factory</literal> element. Once
defined, the configuration associated with the factory pid will automatically create (or remove) bean instances which will be registered (or unregistered)
in the OSGi space based on a <emphasis>template</emphasis> bean definition and the CM configuration.</para>
<para>This might sound more complicated then it actually is, so let's look at a simplistic example:</para>
<programlistingco>
<areaspec>
<area id="compendium:msf:def.1:fpid" coords="2 100"/>
<area id="compendium:msf:def.1:ae" coords="3 100"/>
<area id="compendium:msf:def.1:bean.template" coords="5 100"/>
</areaspec>
<programlisting language="java"><![CDATA[<osgix:managed-service-factory id="simple-msf"
factory-pid="com.xyz.messageservice"
auto-export="all-classes">
<bean class="com.xyz.MessageTank"/>
</osgix:managed-service-factory>]]></programlisting>
<calloutlist>
<callout arearefs="compendium:msf:def.1:fpid">
<para>factory persistent id (pid)</para>
</callout>
<callout arearefs="compendium:msf:def.1:ae">
<para>Shortcut flag used to determine under what interfaces the OSGi service is published (more info below)</para>
</callout>
<callout arearefs="compendium:msf:def.1:bean.template">
<para>bean definition <emphasis>template</emphasis>. For each detected configuration, a new service will be created using
the bean definition template.</para>
</callout>
</calloutlist>
</programlistingco>
<para>In its simplest form, the <literal>managed-service-factory</literal> requires the <emphasis>factory pid</emphasis>, a <emphasis>bean definition</emphasis>
used as a template and some information on how possible bean instances are published as services. Basically, the definition above instructs
Gemini Blueprint to monitor the given factory pid (through a dedicated <interfacename>ManagedServiceFactory</interfacename> implementation (see the Compendium Spec for
more info)) and for every <interfacename>Configuration</interfacename> object associated with the factory pid, to create a new, anonymous instance of
the nested bean declared and export that instance as an OSGi service. The lifecycle of these beans instances is tied to the lifecycle of the
associated <interfacename>Configuration</interfacename> objects. If a new configuration is added, a new bean is created and exported.
If a configuration object is deleted or disassociated from the factory pid then the corresponding bean instance is destroyed.</para>
<para>In many regards, <literal>managed-service-factory</literal> acts as a specialized service exporter, similar to the
<link linkend="service-registry:export"><literal>service</literal></link> element but supporting the concept of
<link linkend="compendium:cm:managed-properties">managed properties</link>. In fact, many of
<literal>service</literal>'s attributes that indicate how a bean is exported, are found in <literal>managed-service-factory</literal> (as you saw in the
previous example with <literal>auto-export</literal>) as are the <literal>managed-properties</literal> attributes.</para>
<para>The list of attributes can be found below:</para>
<table id="compendium-cm-msf-options" pgwide="1" align="center">
<title>Managed Service Factory Options</title>
<tgroup cols="6">
<colspec colname="c1"/>
<colspec colname="c2"/>
<colspec colname="c3"/>
<colspec colname="c4"/>
<colspec colname="c5"/>
<colspec colname="c6"/>
<spanspec spanname="values" namest="c2" nameend="c5" align="center"/>
<thead>
<row>
<entry>Name</entry>
<entry spanname="values">Values</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>interface</entry>
<entry spanname="values">fully qualified class name (such as <classname>java.lang.Thread</classname>)</entry>
<entry>the fully qualified name of the class under which the object will be exported</entry>
</row>
<row>
<entry>context-class-loader</entry>
<entry namest="c2" nameend="c3">unmanaged</entry>
<entry namest="c4" nameend="c5">service-provider</entry>
<entry>Defines how the context class loader will be managed when an operation is invoked on the
exported service. The default value is <literal>unmanaged</literal> which means that no management of
the context class loader is attempted. A value of <literal>service-provider</literal> guarantees that
the context class loader will have visibility of all the resources on the class path of
bundle exporting the service.</entry>
</row>
<row>
<entry>auto-export</entry>
<entry>disabled <literal>(default)</literal></entry>
<entry>interfaces</entry>
<entry>class-hierarchy</entry>
<entry>all-classes</entry>
<entry>Enables Spring to automatically manage the set of service interfaces advertised for the
service. By default this facility is <literal>disabled</literal>. A value of <literal>interfaces</literal> advertises all
of the Java interfaces supported by the exported service. A value of <literal>class-hierarchy</literal>
advertises all the Java classes in the hierarchy of the exported service. A value of
<literal>all-classes</literal> advertises all Java interfaces and classes.</entry>
</row>
<row>
<entry>autowire-on-update</entry>
<entry namest="c2" nameend="c3">false <literal>(default)</literal></entry>
<entry namest="c4" nameend="c5">true</entry>
<entry>Whether or not the container should autowire the target bean everytime an update occurs.
When <literal>true</literal> is specified, the container will perform autowire (by name) the bean instance with the
newly set properties. In case <literal>update-method</literal> attribute is used as well, the autowiring process will
take precedence.</entry>
</row>
<row>
<entry>update-method</entry>
<entry namest="c2" nameend="c3">none <literal>(default)</literal></entry>
<entry namest="c4" nameend="c5">someMethod</entry>
<entry>The update method to invoke whenever an update occurs in the configuration data. Allows the target
bean to process the update information itself. In case <literal>autowire-on-update</literal> is also used, the <literal>update-method</literal>
will be invoked after the autowiring takes place.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>Similar to the <literal>service</literal> element, a list of interfaces or/and registration listeners can be declared to be notified when a
service is being registered/unregistered. For more information on the semantics, please see <xref linkend="service-registry:export:intfs"/> and
<xref linkend="service-registry:export:lifecycle"/> chapters.</para>
<para>Now that the <literal>managed-service-factory</literal> options have been explained, let's look at a more complex configuration:</para>
<programlistingco>
<areaspec>
<area id="compendium:msf:def.2:fpid" coords="4 100"/>
<area id="compendium:msf:def.2:us" coords="5 100"/>
<area id="compendium:msf:def.2:um" coords="6 100"/>
<areaset id="compendium:msf:def.2:intfs" coords="">
<area id="compendium:msf:def.2:intfs.1" coords="8 100"/>
<area id="compendium:msf:def.2:intfs.2" coords="9 100"/>
</areaset>
<area id="compendium:msf:def.2:list.def" coords="11 100"/>
<area id="compendium:msf:def.2:list.cm.1" coords="12 100"/>
<area id="compendium:msf:def.2:list.cm.2" coords="13 100"/>
<area id="compendium:msf:def.2:tmpl" coords="15 100"/>
</areaspec>
<programlisting language="xml"><![CDATA[<bean id="queueTracker" class="org.xyz.queue.QueueTracker"/>
<osgix:managed-service-factory id="data-msf"
factory-pid="org.xyz.labX"
autowire-on-update="true"
update-method="refresh">
<osgix:interfaces>
<value>java.util.Collection</value>
<value>java.util.Queue</value>
</osgix:interfaces>
<osgix:registration-listener ref="queueTracker"
registration-method="track"
unregistration-method="untrack"/>
<bean class="com.xyz.ResizableQueue">
<property name="size" value="100"/>
<property name="concurrency" value="10"/>
<property name="fair" value="false"/>
</bean>
</osgix:managed-service-factory>]]></programlisting>
<calloutlist>
<callout arearefs="compendium:msf:def.2:fpid">
<para><interfacename>ManagedServiceFactory</interfacename> factory persistent id</para>
</callout>
<callout arearefs="compendium:msf:def.2:us">
<para>whether Gemini Blueprint should autowire the bean when a <interfacename>Configuration</interfacename> is updated</para>
</callout>
<callout arearefs="compendium:msf:def.2:um">
<para>the method to invoke after autowiring</para>
</callout>
<callout arearefs="compendium:msf:def.2:intfs">
<para>the interfaces under which the nested beans are published as OSGi services</para>
</callout>
<callout arearefs="compendium:msf:def.2:list.def">
<para>listener notified when a service (based on the CM <interfacename>Configuration</interfacename>) is registered/unregistered</para>
</callout>
<callout arearefs="compendium:msf:def.2:list.cm.1">
<para>custom (optional) service registration method</para>
</callout>
<callout arearefs="compendium:msf:def.2:list.cm.2">
<para>custom (optional) service unregistration method</para>
</callout>
<callout arearefs="compendium:msf:def.2:tmpl">
<para>bean definition template</para>
</callout>
</calloutlist>
</programlistingco>
<para>The example above, creates a imaginary <classname>ResizeableQueue</classname> instance for each <interfacename>Configuration</interfacename> entry
present under the <literal>org.xyz.labX</literal> factory pid. Each instance has default values assigned to <literal>size</literal>, <literal>concurrency</literal>
and <literal>fair</literal> parameters. However, just like <literal>managed-properties</literal>, during the bean creation, the values received from the
Configuration Admin will be injected by name, possibly overriding existing settings. Once created and configured, each nested, anonymous bean instance
is registered as an OSGi service under the <interfacename>java.util.Collection</interfacename> and <interfacename>java.util.Queue</interfacename>
interfaces. The OSGi service lifecycle is monitored by a registration listener, namely the bean <literal>queueTracker</literal>.
Finally, due to the specified <literal>autowire-on-update</literal> and <literal>update-method</literal> attributes, any updates executed to each CM configuration
will cause the container to autowire the associated bean instance with the newly set properties and after that a
<methodname>refresh</methodname> callback will be invoked on it.</para>
</section>
<section id="compendium:cm:dict">
<title>Direct Access To Configuration Data</title>
<para>The simplest way to work directly with the configuration data stored under a given persistent id or factory persistent id,
is to register a service that implements either the <interfacename>ManagedService</interfacename> or <interfacename>ManagedServiceFactory</interfacename>
interface and specify the pid that you are interested in as a service property (for more information, see the Configuration Admin chapter
in the OSGi compendium spec). For example:</para>
<programlisting language="xml"><![CDATA[<osgi:service interface="org.osgi.service.cm.ManagedService" ref="myManagedService">
<osgi:service-properties>
<entry key="service.pid" value="my.managed.service.pid"/>
</osgi:service-properties>
</osgi:service>
<bean id="myManagedService" class="com.xyz.MyManagedService"/>]]></programlisting>
</section>
</section>
</chapter>