blob: f51baaae7712e690db43ae45d94af96f9ae2fce9 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Dependency Manager - Annotations :: Apache Felix</title>
<link rel="canonical" href="https://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/guides/annotations.html">
<meta name="generator" content="Antora 2.3.4">
<link rel="stylesheet" href="../../../../_/css/site.css">
<link rel="icon" href="../../../../_/img/favicon.png" type="image/x-icon">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://felix.apache.org/index.html">
<span>
<img src="../../../../_/img/logo.png">
</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<div class="navbar-end">
<a class="navbar-item" href="https://felix.apache.org/index.html">Home</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Subprojects</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="../../apache-felix-dependency-manager.html">Dependency Manager</a>
<a class="navbar-item" href="../../apache-felix-event-admin.html">Event Admin</a>
<a class="navbar-item" href="../../apache-felix-file-install.html">File Install</a>
<a class="navbar-item" href="../../apache-felix-framework.html">Framework</a>
<a class="navbar-item" href="../../apache-felix-gogo.html">Gogo Shell</a>
<a class="navbar-item" href="../../apache-felix-healthchecks.html">Health Checks</a>
<a class="navbar-item" href="../../apache-felix-inventory.html">Inventory</a>
<a class="navbar-item" href="../../apache-felix-log.html">Log</a>
<a class="navbar-item" href="../../apache-felix-logback.html">Logback</a>
<a class="navbar-item" href="../../apache-felix-maven-bundle-plugin.html">Maven bundle plugin</a>
<a class="navbar-item" href="../../apache-felix-maven-scr-plugin.html">Maven SCR plugin</a>
<a class="navbar-item" href="../../apache-felix-metatype-service.html">Metatype Service</a>
<a class="navbar-item" href="../../apache-felix-preferences-service.html">Preferences Service</a>
<a class="navbar-item" href="../../apache-felix-remote-shell.html">Remote Shell</a>
<a class="navbar-item" href="../../apache-felix-script-console-plugin.html">Script console plugin</a>
<a class="navbar-item" href="../../apache-felix-shell.html">Lightweight shell</a>
<a class="navbar-item" href="../../apache-felix-shell-tui.html">Shell TUI</a>
<a class="navbar-item" href="../../apache-felix-web-console.html">Web Console</a>
</div>
</div>
<div class="navbar-item">
<span class="control">
<a class="button is-primary" href="../../../downloads.html">Downloads</a>
</span>
</div>
</div>
</div>
</nav>
</header>
<div class="body">
<div class="nav-container" data-component="documentation" data-version="master">
<aside class="nav">
<div class="panels">
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../../../index.html">Documentation</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../documentation.html">Documentation</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../downloads.html">Downloads</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../getting-started.html">Getting Started</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../news.html">News</a>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Community</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../community/project-info.html">Apache Felix Project Info</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../community/contributing.html">Contributing</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../community/projects-using-felix.html">Projects Using Felix</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<span class="nav-text">Development</span>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/coding-standards.html">Coding Standards</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/dependencies-file-template.html">DEPENDENCIES file template</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/provisional-osgi-api-policy.html">Provisional OSGi API Policy</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/release-management-nexus.html">Release Management</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/site-how-to.html">Site How To</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../development/using-the-osgi-compliance-tests.html">Using the OSGi Compliance Tests</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../../faqs.html">FAQS</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../faqs/apache-felix-bundle-plugin-faq.html">Apache Felix Bundle Plugin Frequently Asked Questions</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../faqs/apache-felix-scr-plugin-faq.html">Apache Felix SCR Plugin Frequently Asked Questions</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../../subprojects.html">Subprojects</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<span class="nav-text">Guides</span>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="migrating-from-earlier-versions.html">Apache Felix Dependency Manager - Migrating from earlier versions</a>
</li>
<li class="nav-item is-current-page" data-depth="4">
<a class="nav-link" href="annotations.html">Dependency Manager - Annotations</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="background.html">Dependency Manager - Background</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="bundles-and-dependencies.html">Dependency Manager - Bundles and Dependencies</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="design-patterns.html">Dependency Manager - Design Patterns</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="development.html">Dependency Manager - Development</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="history.html">Dependency Manager - History</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="javadocs.html">Dependency Manager - JavaDocs</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="migrating-from-other-solutions.html">Dependency Manager - Migrating from other solutions.</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="performance-tuning.html">Dependency Manager - Performance Tuning</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="resources.html">Dependency Manager - Resource adapters</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="whatsnew.html">Dependency Manager - What&#8217;s new in version 4?</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="dm-lambda.html">Dependency Manager Lambda</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="whatsnew-r15.html">What&#8217;s New in R15</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<span class="nav-text">Reference</span>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-adapter.html">Dependency Manager - Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-aspect.html">Dependency Manager - Aspect</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-bundle-adapter.html">Dependency Manager - Bundle Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dependency-bundle.html">Dependency Manager - Bundle Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/components.html">Dependency Manager - Components</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dependency-configuration.html">Dependency Manager - Configuration Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dependencies.html">Dependency Manager - Dependencies</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/external-links.html">Dependency Manager - External Links</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-factory-configuration-adapter.html">Dependency Manager - Factory Configuration Adapter Service</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-resource-adapter.html">Dependency Manager - Resource Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dependency-resource.html">Dependency Manager - Resource Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dependency-service.html">Dependency Manager - Service Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/service-scopes.html">Dependency Manager - Service Scopes</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/component-singleton.html">Dependency Manager - Singleton Component</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/thread-model.html">Dependency Manager - Thread Model</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../reference/dm-annotations.html">Dependency Manager Annotations</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<span class="nav-text">Tutorials</span>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../tutorials/working-with-annotations.html">Dependency Manager - Annotations</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../tutorials/getting-started.html">Dependency Manager - Getting Started</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../tutorials/leveraging-the-shell.html">Dependency Manager - Leveraging the shell</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../tutorials/sample-code.html">Dependency Manager sample projects</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-event-admin.html">Apache Felix Event Admin</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-file-install.html">Apache Felix File Install</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../apache-felix-framework.html">Apache Felix Framework</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-bundle-cache.html">Apache Felix Framework Bundle Cache</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-configuration-properties.html">Apache Felix Framework Configuration Properties</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-faq.html">Apache Felix Framework Frequently Asked Questions</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-launching-and-embedding.html">Apache Felix Framework Launching and Embedding</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-usage-documentation.html">Apache Felix Framework Usage Documentation</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-framework-security.html">Apache Felix Framework Security</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../apache-felix-gogo.html">Apache Felix Gogo</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-gogo/rfc-147-overview.html">RFC 147 Overview</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-healthchecks.html">Apache Felix Health Checks</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-inventory.html">Apache Felix Inventory Printer</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-log.html">Apache Felix Log</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-logback.html">Apache Felix Logback</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-maven-bundle-plugin-bnd.html">Apache Felix Maven Bundle Plugin (BND)</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-metatype-service.html">Apache Felix Metatype Service</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-osgi-bundle-repository.html">Apache Felix OSGi Bundle Repository (OBR)</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-preferences-service.html">Apache Felix Preferences Service</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-remote-shell.html">Apache Felix Remote Shell</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-shell.html">Apache Felix Shell</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../apache-felix-shell-tui.html">Apache Felix Shell TUI</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../apache-felix-web-console.html">Apache Felix Web Console</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console.html">Extending the Apache Felix Web Console</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-web-console/web-console-restful-api.html">Web Console RESTful API</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-web-console/web-console-security-provider.html">Web Console Security Provider</a>
</li>
<li class="nav-item" data-depth="3">
<button class="nav-item-toggle"></button>
<span class="nav-text">Extensions</span>
<ul class="nav-list">
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/branding-the-web-console.html">Branding the Web Console</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/providing-resources.html">Providing Resources</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/providing-web-console-plugins.html">Providing Web Console Plugins</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/web-console-logging.html">Web Console Logging</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/web-console-output-templating.html">Web Console Output Templating</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">Maven SCR plugin</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-maven-scr-plugin-use.html">Apache Felix Maven SCR Plugin Use</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-scr-bndtools-use.html">Apache Felix SCR Annotations BndTools Use</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-scr-ant-task-use.html">Apache Felix SCR Ant Task Use</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/extending-scr-annotations.html">Extending SCR Annotations Excerpt: How add new Annotations extending the base Annotations</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/scr-annotations.html">SCR Annotations Excerpt: Using Java 5 Annotations to describe the component or service.</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../apache-felix-maven-scr-plugin/scr-javadoc-tags.html">SCR JavaDoc Tags Excerpt: Using JavaDoc Tags to describe the component or service.</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../../../tutorials-examples-and-presentations.html">Tutorials</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-application-demonstration.html">Apache Felix Application Demonstration</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial.html">Apache Felix OSGi Tutorial</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-faq.html">OSGi Frequently Asked Questions</a>
</li>
<li class="nav-item" data-depth="2">
<button class="nav-item-toggle"></button>
<span class="nav-text">OSGI Tutorial</span>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-1.html">Apache Felix Tutorial Example 1 - Service Event Listener Bundle</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-2.html">Apache Felix Tutorial Example 2</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-2b.html">Apache Felix Tutorial Example 2b</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-3.html">Apache Felix Tutorial Example 3</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-4.html">Apache Felix Tutorial Example 4</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-5.html">Apache Felix Tutorial Example 5</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-6.html">Example 6 - Spell Checker Service Bundle</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-7.html">Example 7 - Spell Checker Client Bundle</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-8.html">Example 8 - Spell Checker Service using Service Binder</a>
</li>
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-9.html">Example 9 - Spell Checker Service using Declarative Services</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../license.html">Apache License 2.0</a>
</li>
<li class="nav-item" data-depth="1">
<a class="nav-link" href="../../../site-map.html">Site map</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Documentation</span>
<span class="version">master</span>
</div>
<ul class="components">
<li class="component is-current">
<span class="title">Documentation</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../../../index.html">master</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main class="article">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../../index.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../../../index.html">Documentation</a></li>
<li><a href="../../../subprojects.html">Subprojects</a></li>
<li><a href="../../apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a></li>
<li>Guides</li>
<li><a href="annotations.html">Dependency Manager - Annotations</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/felix-antora-site/edit/main/modules/ROOT/pages/subprojects/apache-felix-dependency-manager/guides/annotations.adoc">Edit this Page</a></div>
</div>
<div class="content">
<article class="doc">
<h1 class="page">Dependency Manager - Annotations</h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This section presents a quick overview of the capabilities and usage of the DependencyManager Java annotations.
In particular, we will recap the DependencyManager annotation architecture, and identify some simple usage scenarios using a SpellChecker sample application with annotated components.
The application is available from the felix trunk, in the <code>dependencymanager/samples.annotation</code> subproject.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_architecture"><a class="anchor" href="#_architecture"></a>Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Instead of writing Activators which extends the DependencyActivatorBase class, service components can now be annotated using the annotations provided by the <em>org.apache.felix.dependencymanager.annotation</em> bundle.
Annotations are not reflectively parsed at runtime;
but we use a BND plugin which scans annotations at compilation phase and generates a compact metadata file in the bundle&#8217;s META-INF/dependencymanager subdirectory.
This has the following benefits:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>JVM startup speed is not affected, and class files are not parsed when the framework is starting</p>
</li>
<li>
<p>Moreover, since the annotations are not retained by the VM at runtime, it is not necessary to load the annotation API bundle at runtime.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>At runtime, the metadata generated during the compilation phase are processed by a specific DependencyManager Runtime bundle, which is in charge of managing the service component lifecycle and dependencies.
This Runtime bundle actually uses the DependencyManager programmatic API in order to manage the annotated components.
Annotated components can then be inspected with the DependencyManager Gogo shell, as it is the case with DM components declared through the programmatic DM API.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_registering_a_service"><a class="anchor" href="#_registering_a_service"></a>Registering a Service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To register a service, your can annotate your class with a <em>@Component</em> annotation, and an instance of your class will be registered under all directly implemented interfaces into the OSGi registry.
You can however take control on the interfaces to be exposed, and in this case, you can use the <em>provides</em> attribute, which takes a list of classes to expose from the registry.</p>
</div>
<div class="paragraph">
<p>To illustrate this, we are now introducing a SpellChecker application which provides a Felix "spellcheck" Gogo shell command.
Gogo is the new shell supported by the Felix Framework.
Our "spellcheck" command is implemented by the SpellChecker component which accepts a string as parameter.
This string is then checked for proper existence.
To do the checking, The SpellChecker class has a required/multiple (1..N) dependency over every available DictionaryService services.
Such DictionaryService represents a real dictionary for a given language (it has a <em>lang</em> service property), and is configurable/instantiable from the OSGi Configuration Admin Service.</p>
</div>
<div class="paragraph">
<p>Configuration Admin service provides a mechanism for configuring components (using ManagedService interfaces), and WebConsole actually implements this service.
ConfigAdmin is also able to instantiate some Services (using ManagedServiceFactory interfaces).</p>
</div>
<div class="paragraph">
<p>Now we have introduced the background, here is the SpellCheck component:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Component(provides={SpellChecker.class},
properties={@Property(name=CommandProcessor.COMMAND_SCOPE, value="dmsample.annotation"),
@Property(name=CommandProcessor.COMMAND_FUNCTION, values={"spellcheck"})})
public class SpellChecker {
// --- Gogo Shell command
@Descriptor("checks if word is found from an available dictionary")
public void spellcheck(@Descriptor("the word to check")String word) {
// Check the proper existence of the word parameter, using injected DictionaryService instances
// ...
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the code above, you see that the SpellCheck is annotated with the <em>@Component</em> annotation.
Gogo runtime does not required shell commands to implement a specific interface.
Commands just have to register some Pojos in the OSGi registry, but the only thing required is to provide the Pojos with two service properties ( COMMAND_SCOPE, and COMMAND_FUNCTION) which will be used by the Gogo runtime when instropecting the Pojo for invoking the proper functions.</p>
</div>
<div class="paragraph">
<p>So, coming back to the sample code, the SpellChecker class registers itself into the OSGi registry, using the <em>provides</em> attribute, which just refer to our SpellChecker class, and the two mandatory Gogo service properties are also specified using the <em>@Property</em> annotation.
It is not shown here, but service properties can also be provided dynamically from a method that can return a Map, and annotated with the <em>@Start</em> lifecycle callback, but we will see this feature in a another section.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_depending_on_a_service"><a class="anchor" href="#_depending_on_a_service"></a>Depending on a Service</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Our SpellChecker component can expose itself as a Gogo shell command, but before being registered into the OSGi registry, we also need to be injected with two dependencies: one required dependency (at minimum) on a DictionaryService, and another optional one on a LogService.
First, let&#8217;s look at the DictionaryService, which is a simple interface:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> public interface DictionaryService {
/**
* Check for the existence of a word.
* @param word the word to be checked.
* @return true if the word is in the dictionary, false otherwise.
*/
public boolean checkWord(String word);
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And here is our previous SpellChecker component, augmented with two new ServiceDependency annotations:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Component(provides={SpellChecker.class},
properties={@Property(name=CommandProcessor.COMMAND_SCOPE, value="dmsample.annotation"),
@Property(name=CommandProcessor.COMMAND_FUNCTION, values={"spellcheck"})})
public class SpellChecker {
@ServiceDependency(required = false)
private LogService m_log;
private CopyOnWriteArrayList&lt;DictionaryService&gt; m_dictionaries = new CopyOnWriteArrayList&lt;DictionaryService&gt;();
@ServiceDependency(removed = "removeDictionary")
protected void addDictionary(DictionaryService dictionary) {
m_dictionaries.add(dictionary);
}
protected void removeDictionary(DictionaryService dictionary) {
m_dictionaries.remove(dictionary);
}
// --- Gogo Shell command
@Descriptor("checks if word is found from an available dictionary")
public void spellcheck(@Descriptor("the word to check")String word) {
m_log.log(LogService.LOG_INFO, "Checking spelling of word \"" + word
+ "\" using the following dictionaries: " + m_dictionaries);
for (DictionaryService dictionary : m_dictionaries) {
if (dictionary.checkWord(word)) {
System.out.println("word " + word + " is correct");
return;
}
}
System.err.println("word " + word + " is incorrect");
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>There are many things to describe in the code above:</p>
</div>
<div class="paragraph">
<p>First, we define an optional dependency on the LogService, by defining a <em>@ServiceDependency(required=false)</em> annotation on our m_logService field: This means that our component will be provided into the OSGi registry even if there is no available LogService, and in this case, a NullObject will be injected in our class field;
This will avoid to check for nullability, when using the m_logService field.
All optional dependencies applied on class fields are injected with a NullObject (when not available).
The NullObject can be invoked and will do nothing.
For a lot of cases that is good enough to handle optional dependencies.
But when you really want to check if an optional service is there or not, then you have to apply the optional dependency on a callback method, which will be called when the optional service is available.</p>
</div>
<div class="paragraph">
<p>Next comes the dependency on the DictionaryService.
Here, we use a <em>ServiceDependency</em> annotation, but this time we apply it on a method (<em>add/removeDictionary</em>).
There is no need to specify the "<em>required=true</em>" flag because it is the default value.
Notice that this behavior is different from the API, where service dependencies are optional by default . We use a callback method, because we just need to register all available DictionaryService services in our dictionary list, which is used when checking word existence.
This list is a copy on write list because the dependency may be injected at any time, possibly from another thread.
So, using a copy on write list avoid us to use synchronized methods.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_creating_a_service_from_configadmin"><a class="anchor" href="#_creating_a_service_from_configadmin"></a>Creating a Service from ConfigAdmin</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <em>@Component</em> annotation is not the only one for creating services.
Another one is the <em>@FactoryConfigurationAdapterService</em> annotation which allows to instantiate many instances of the same annotated service class from ConfigAdmin (and WebConsole).
To illustrate this, let&#8217;s take a look at our DictionaryImpl class which is part of the SpellChecker sample.
This service is required by the SpellChecker component, when checking for proper word existence.
And you can instantiate as many DictionaryService as you want, from ConfigAdmin &#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@FactoryConfigurationAdapterService(factoryPid="DictionaryImplFactoryPid", updated="updated")
public class DictionaryImpl implements DictionaryService {
/**
* We store all configured words in a thread-safe data structure, because ConfigAdmin
* may invoke our updated method at any time.
*/
private final CopyOnWriteArrayList&lt;String&gt; m_words = new CopyOnWriteArrayList&lt;String&gt;();
/**
* Our Dictionary language.
*/
private String m_lang;
/**
* Our service will be initialized from ConfigAdmin, and we also handle updates in this method.
* @param config The configuration where we'll lookup our words list (key="words").
*/
protected void updated(Dictionary&lt;String, ?&gt; config) {
m_lang = (String) config.get("lang");
m_words.clear();
String[] words = (String[]) config.get("words");
for (String word : words) {
m_words.add(word);
}
}
/**
* Check if a word exists if the list of words we have been configured from ConfigAdmin/WebConsole.
*/
public boolean checkWord(String word) {
return m_words.contains(word);
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Our DictionaryImpl class implements a DictionaryService, and our class will be registered under that interface (all directly implemented interfaces are used when registering the service, but you can select some others using the <em>provides</em> attribute).
The <em>@FactoryConfigurationAdapterService</em> annotation will instantiate our service for each configuration created from web console (and matching our "DictionaryImplFactoryPid" factoryPid).</p>
</div>
<div class="paragraph">
<p>We also use the <em>updated</em> attribute, which specifies a callback method which will handle properties configured by ConfigAdmin.
The updated callback will also be called when our properties are changing.
Every properties are propagated to our service properties, unless the properties starting with a dot (".").
Configuration properties starting with a dot (".") are considered private and are not propagated.</p>
</div>
<div class="paragraph">
<p>Notice that you can mix standard bnd metatype annotations with DM annotations, in order describe configurations meta data (default values, property labels, etc &#8230;&#8203;
see <a href="http://bnd.bndtools.org/chapters/210-metatype.html" class="bare">http://bnd.bndtools.org/chapters/210-metatype.html</a>).
So, let&#8217;s revisit our DisctionaryImpl service, but this time with meta type support:</p>
</div>
<div class="paragraph">
<p>First, we define an interface for describing our configuration metadata, with bnd metatype annotations:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import java.util.List;
import aQute.bnd.annotation.metatype.Meta.AD;
import aQute.bnd.annotation.metatype.Meta.OCD;
@OCD(name="Spell Checker Dictionary (annotation)", factory = true, description = "Declare here some Dictionary instances")
public interface DictionaryConfiguration {
@AD(description = "Describes the dictionary language", deflt = "en")
String lang();
@AD(description = "Declare here the list of words supported by this dictionary. This properties starts with a Dot and won't be propagated with Dictionary OSGi service properties")
List&lt;String&gt; words();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Next, here is our DictionaryImpl that will use the bnd "Configurable" helper in order to retrieve the actual configuration:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
import org.apache.felix.dm.annotation.api.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.osgi.service.log.LogService;
import aQute.bnd.annotation.metatype.Configurable;
@FactoryConfigurationAdapterService(factoryPidClass = DictionaryConfiguration.class, propagate = true, updated = "updated")
public class DictionaryImpl implements DictionaryService {
private final CopyOnWriteArrayList&lt;String&gt; m_words = new CopyOnWriteArrayList&lt;String&gt;();
private String m_lang;
protected void updated(Dictionary&lt;String, ?&gt; config) {
if (config != null) {
// use bnd "Configurable" helper to get an implementation for our DictionaryConfiguration.
DictionaryConfiguration cnf =
Configurable.createConfigurable(DictionaryConfiguration.class, config);
m_lang = cnf.lang();
m_words.clear();
for (String word : cnf.words()) {
m_words.add(word);
}
}
}
public boolean checkWord(String word) {
return m_words.contains(word);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_providing_an_aspect"><a class="anchor" href="#_providing_an_aspect"></a>Providing an Aspect</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As we have seen in the previous section, there are many annotations that can be used to specify a service.
Another one is the <em>@AspectService</em> annotation.
This annotation allows to <em>decorate</em> an existing service in order to add certain "capabilities" to it, like adding a specific caching mechanism to a storage service or implementing logging.
Aspects can be plugged to an existing service at runtime, and can also be removed dynamically.
This is transparent, and the clients using the existing service are not interrupted, they are just rebound with the aspect service.</p>
</div>
<div class="paragraph">
<p>As an example, we go back to our SpellChecker application, and we are now looking at the DictionaryAspect class.
This class uses the <em>@Aspect</em> Service annotation in order to add some custom words to an English DictionaryService (with the service property lang=en).
The Extra words to add to the English Dictionary will be configured from ConfigAdmin.
That&#8217;s why the class also uses a <em>@ConfigurationDependency</em> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@AspectService(ranking = 10, filter = "(lang=en)")
public class DictionaryAspect implements DictionaryService {
/**
* This is the service this aspect is applying to.
*/
private volatile DictionaryService m_originalDictionary;
/**
* We store all configured words in a thread-safe data structure, because ConfigAdmin may
* invoke our updated method at any time.
*/
private CopyOnWriteArrayList&lt;String&gt; m_words = new CopyOnWriteArrayList&lt;String&gt;();
/**
* Defines a configuration dependency for retrieving our english custom words (by default,
* our PID is our full class name).
*/
@ConfigurationDependency
protected void updated(Dictionary&lt;String, ?&gt; config) {
m_words.clear();
String[] words = (String[]) config.get("words");
for (String word : words) {
m_words.add(word);
}
}
/**
* Checks if a word is found from our custom word list. if not, delegate to the decorated
* dictionary.
*/
public boolean checkWord(String word) {
if (m_words.contains(word)) {
return true;
}
return m_originalDictionary.checkWord(word);
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The annotation does the following: because our class implements the DictionaryService contract, it will instantiate our service each time it finds another existing DictionaryService matching the filter attribute we provide in the annotation (filter="(lang=en)").
And it will inject the existing service in our m_originalDictionary field, by reflection.
But we can also specify a field attribute in the annotation, if we want to explicitly inject the existing service in a given class field.
So, any client depending on an English DictionaryService will be transparently rebound to our aspect Dictionary.</p>
</div>
<div class="paragraph">
<p>In the Annotation, also notice the <em>ranking</em> attribute: It is the level used to organize the aspect chain ordering (multiple aspects may be applied on a given service).</p>
</div>
<div class="paragraph">
<p>The <em>ConfigurationDependency</em> is another dependency that we have not seen before: it is used to configure the extra English words from ConfigAdmin.
This annotation normally requires a pid parameter, which is a persistent identifier uniquely identifying our component, but by default, the pid is set to the fully qualified name of our class.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_how_to_run_the_sample_code"><a class="anchor" href="#_how_to_run_the_sample_code"></a>How to run the sample code</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Just import the Dependency source distribution in bndtools and check the following samples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/annot/README</p>
</li>
<li>
<p>org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/dictionary/api/README</p>
</li>
</ul>
</div>
</div>
</div>
</article>
<aside class="toc sidebar" data-title="Contents" data-levels="2">
<div class="toc-menu"></div>
</aside>
</div>
</main>
</div>
<footer class="footer">
<p>Content licensed under AL2. UI licensed under MPL-2.0 with extensions licensed under AL2</p>
</footer>
<script src="../../../../_/js/site.js"></script>
<script async src="../../../../_/js/vendor/highlight.js"></script>
</body>
</html>