Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 84C8410F3D for ; Sun, 22 Sep 2013 19:52:35 +0000 (UTC) Received: (qmail 6753 invoked by uid 500); 22 Sep 2013 19:52:33 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 6722 invoked by uid 500); 22 Sep 2013 19:52:29 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 6710 invoked by uid 99); 22 Sep 2013 19:52:28 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 22 Sep 2013 19:52:28 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 22 Sep 2013 19:52:26 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7FA2D238890B; Sun, 22 Sep 2013 19:52:06 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1525418 - /felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext Date: Sun, 22 Sep 2013 19:52:06 -0000 To: commits@felix.apache.org From: pderop@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130922195206.7FA2D238890B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: pderop Date: Sun Sep 22 19:52:06 2013 New Revision: 1525418 URL: http://svn.apache.org/r1525418 Log: CMS migration ... Modified: felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext Modified: felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext URL: http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext?rev=1525418&r1=1525417&r2=1525418&view=diff ============================================================================== --- felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext (original) +++ felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager/apache-felix-dependency-manager-using-annotations/dependencymanager-annotations-lifecycle.mdtext Sun Sep 22 19:52:06 2013 @@ -18,40 +18,41 @@ and reactivated, depending on the depart manager which is in charge of maintaining the state of components is implemented in the DM Runtime bundle (org.apache.felix.dm.runtime bundle). -## Lifecycle Callbacks +## Lifecycle callbacks ### Component Activation Activating a component consists of the following steps: - 1. Wait for all required dependencies to be available. When all required dependencies are available: +- Wait for all required dependencies to be available. When all required dependencies are available: -- Instantiate the component. -- Inject all required dependencies (on class fields using reflection, or by invoking + - Instantiate the component. + - Inject all required dependencies (on class fields using reflection, or by invoking callback methods). -- Inject all optional dependencies defined on class fields, possibly with a *NullObject* if the dependency is not available. -- Call the component init method (annotated with *@Init*). In the Init method, you are + - Inject all optional dependencies defined on class fields, possibly with a *NullObject* if the dependency is not available. + - Call the component init method (annotated with *@Init*). In the Init method, you are yet allowed to add some additional dependencies (but using the API). Alternatively, you can also configure some dependencies dynamically (explained later, in [#Dynamic Dependency Configuration](#dynamic-dependency-configuration). - 1. Wait for extra dependencies optionally configured from the init() method. - 1. If the component is not using the @*LifecycleController* annotation (detailed in the +- Wait for extra dependencies optionally configured from the init() method. +- If the component is not using the @*LifecycleController* annotation (detailed in the [#Controlling the Lifecycle](#controlling-the-lifecycle.path) section), then: -- Invoke the component start method (annotated with *@Start*). -- Publish some OSGi services (if the component provides some services). -- Start tracking optional dependencies applied on method callbacks (useful for the whiteboard pattern). *Notice that NullObject pattern is not applied to optional callback dependencies*. In other words, if the dependency is not there, your callback won't be invoked at all. If you need the NullObject pattern, then apply optional dependencies on class fields, not on callback methods. + - Invoke the component start method (annotated with *@Start*). + - Publish some OSGi services (if the component provides some services). + - Start tracking optional dependencies applied on method callbacks (useful for the whiteboard pattern). *Notice that NullObject pattern is not applied to optional callback dependencies*. In other words, if the dependency is not there, your callback won't be invoked at all. If you need the NullObject pattern, then apply optional dependencies on class fields, not on callback methods. - 1. Else do nothing because  the component will trigger itself the startup using the lifecycle controller. +- Else do nothing because the component will trigger itself the startup using the lifecycle controller. ### Component Deactivation Deactivating a component consists of the following steps: -1. If the bundle is stopped or if some required dependencies are unavailable, or if the component is deactivated by a factorySet, then: -1. * Unbind optional dependencies (defined on callback methods). Notice that any optional dependency unavailability does not trigger the component deactivation:  the *removed* callbacks are just invoked, if declared in the annotation. -1. * Invoke the stop method (annotated wit *@Stop*), and unregister some OSGi services (if the components provides some services). -1. * invoke destroy method (annotated with *@Destroy*). -1. * invoke *removed* callbacks for required dependencies, if any. + +- If the bundle is stopped or if some required dependencies are unavailable, or if the component is deactivated by a factorySet, then: + - Unbind optional dependencies (defined on callback methods). Notice that any optional dependency unavailability does not trigger the component deactivation:  the *removed* callbacks are just invoked, if declared in the annotation. + - Invoke the stop method (annotated wit *@Stop*), and unregister some OSGi services (if the components provides some services). + - invoke destroy method (annotated with *@Destroy*). + - invoke *removed* callbacks for required dependencies, if any. ### Example @@ -80,9 +81,9 @@ The following example shows a basic comp } } -### Dynamic Dependency Configuration +## Dynamic Dependency Configuration -#### Rationale +### Rationale We have seen that a component may declare some dependencies and is started when all required dependencies are available. But there are some cases when you may need to define some dependencies filters dynamically, possibly from data picked up from other dependencies (like a configuration dependency for instance). @@ -109,7 +110,7 @@ Then you can return this map from your @ So, after the init method returns, the map will be used to configure the dependency named "foo", which will then be evaluated. And once the dependency is available, then your @Start callback will be invoked. -#### Usage example: +### Usage example: This is an example of a component X whose dependency "foo" filter is configured from ConfigAdmin. First, we defined a ConfigurationDependency in order to get injected with our configuration. Next, we define a dependency on the *FooService*, but this time, we declare the annotation like this: *@ServiceDependency(*{*}{*}name="foo"*{*}*)*. As explained above, The ConfigurationDependency will be injected *before* the @Init method, and the named dependency ("foo") will be calculated *after* the @Init method returns. So, from our Init method, we just return a map which contains the filter and required flag for the "foo" dependency, and we actually use the configuration which has already been injected: @@ -158,7 +159,10 @@ This is an example of a component X whos ## Controlling the Lifecycle -As explained in the *Component Activation* section, a component which provides a service is automatically registered into the OSGi registry, after the @Start method returns. But it is sometimes required to control when the service is really started/published or unpublished/stopped. +As explained in the *Component Activation* section, a component which provides a service +is automatically registered into the OSGi registry, after the @Start method returns. +But it is sometimes required to control when the service is really started/published or +unpublished/stopped. This can be done using the @LifecycleController annotation. This annotation injects a Runnable object that can be invoked once you want to trigger your service startup and publication. @@ -214,11 +218,12 @@ Next, here is our service, which uses th ## Dynamic Service Properties -When a component provides an OSGi Service, the service properties are calculated as the following: +When a component provides an OSGi Service, the service properties are calculated as the +following: -* Any properties specified in the @Component annotation are used to provide the OSGi Service -* Any properties provided by a FactorySet are also inserted in the published service -* Any Dependency whose *propagate* attribute is set to true will also insert its properties to the published service +- Any properties specified in the @Component annotation are used to provide the OSGi Service +- Any properties provided by a FactorySet are also inserted in the published service +- Any Dependency whose *propagate* attribute is set to true will also insert its properties to the published service But when the component needs to specify some service properties dynamically (not statically from the annotation), then it may do so by just returning a Map from the @Start callback. For instance: @@ -246,4 +251,5 @@ Here, the service MyService will be publ - foo2=bar2 (propagated by our ConfigurationDependency dependency) - foo3=bar3 (specified dynamically in the map returned from our start method) -Notice that properties returned by the Map take precedence over other properties, and may override some of them. +Notice that properties returned by the Map take precedence over other properties, and may +override some of them.