blob: 29ac420209c64ba94ac2b490aba9ea895224e262 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8"/>
<title>Apache Tamaya - Extension: Injection</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="Homepage of Apache Tamaya (incubating)"/>
<meta name="author" content="Apache Tamaya Project Team"/>
<meta name="keywords" content="Apache Tamaya Incubating, configuration, Java, ASF, Apache Software Foundation"/>
<meta name="generator" content="JBake ${content.version}"/>
<!-- Le styles -->
<link href="../../css/bootstrap.min.css" rel="stylesheet"/>
<link href="../../css/asciidoctor.css" rel="stylesheet"/>
<link href="../../css/base.css" rel="stylesheet"/>
<link href="../../css/prettify.css" rel="stylesheet"/>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../../js/html5shiv.min.js"></script>
<![endif]-->
<!-- Fav and touch icons from ASF -->
<link rel="shortcut icon" href="../../favicon.ico"/>
<link rel="apple-touch-icon" sizes="57x57" href="../../favicons/apple-touch-icon-57x57.png"/>
<link rel="apple-touch-icon" sizes="60x60" href="../../favicons/apple-touch-icon-60x60.png"/>
<link rel="apple-touch-icon" sizes="72x72" href="../../favicons/apple-touch-icon-72x72.png"/>
<link rel="apple-touch-icon" sizes="76x76" href="../../favicons/apple-touch-icon-76x76.png"/>
<link rel="apple-touch-icon" sizes="114x114" href="../../favicons/apple-touch-icon-114x114.png"/>
<link rel="apple-touch-icon" sizes="120x120" href="../../favicons/apple-touch-icon-120x120.png"/>
<link rel="apple-touch-icon" sizes="144x144" href="../../favicons/apple-touch-icon-144x144.png"/>
<link rel="apple-touch-icon" sizes="152x152" href="../../favicons/apple-touch-icon-152x152.png"/>
<link rel="apple-touch-icon" sizes="180x180" href="../../favicons/apple-touch-icon-180x180.png"/>
<link rel="icon" type="image/png" href="../../favicons/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="../../favicons/favicon-194x194.png" sizes="194x194"/>
<link rel="icon" type="image/png" href="../../favicons/favicon-96x96.png" sizes="96x96"/>
<link rel="icon" type="image/png" href="../../favicons/android-chrome-192x192.png" sizes="192x192"/>
<link rel="icon" type="image/png" href="../../favicons/favicon-16x16.png" sizes="16x16"/>
<link rel="manifest" href="../../favicons/manifest.json"/>
<link rel="shortcut icon" href="../../favicons/favicon.ico"/>
<meta name="msapplication-TileColor" content="#603cba"/>
<meta name="msapplication-TileImage" content="../../favicons/mstile-144x144.png"/>
<meta name="msapplication-config" content="../../favicons/browserconfig.xml"/>
<meta name="theme-color" content="#303284"/>
</head>
<body onload="prettyPrint()">
<div id="wrap">
<div>
<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../../index.html">Tamaya Home</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="../../start.html">Tamaya in 5 minutes</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="../../documentation/usecases.html">Use Cases and Requirements</a></li>
<li><a href="../../documentation/quickstart.html">Quickstart</a></li>
<li><a href="../../documentation/api.html">API</a></li>
<li><a href="../../documentation/core.html">Core</a></li>
<li><a href="../../documentation/extensions.html">Extension Guide</a></li>
<li class="divider"></li>
<li><a href="../../apidocs/stable/index.html">Javadoc 0.4-incubating (release/stable)</a></li>
<li><a href="../../apidocs/development/index.html">Javadoc 0.5-incubating-SNAPSHOT (development)</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Development <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="../../development/source.html">Sources</a></li>
<li><a href="../../development/community.html">Community</a></li>
<li><a href="../../development/team.html">Project Team</a></li>
<li><a target="_blank" href="https://builds.apache.org/view/S-Z/view/Tamaya/">CI / ASF Jenkins</a></li>
<li><a target="_blank" href="https://issues.apache.org/jira/browse/TAMAYA">Issues / ASF Jira</a></li>
<li><a href="../../devguide.html">Development Guide</a></li>
<li><a href="../../release-guide.html">Release Guide</a></li>
<li class="divider"></li>
<li><a href="../../development/possible-contributions.html">Possible Contributions</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Releases <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="../../download.html">Download</a></li>
<li><a href="../../history.html">Release History</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">ASF <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="https://www.apache.org/">Apache Software Foundation (ASF)</a></li>
<li><a href="https://www.apache.org/foundation/how-it-works.html">How the ASF works</a></li>
<li><a href="https://www.apache.org/foundation/getinvolved.html">Get Involved</a></li>
<li><a href="https://www.apache.org/dev/">Developer Resources</a></li>
<li><a href="https://www.apache.org/foundation/policies/conduct.html">Code of Conduct</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
<li><a href="https://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/security">Security</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks</a></li>
<hr/>
<li><a href="https://www.apache.org/events/current-event.html"><img src="https://www.apache.org/events/current-event-125x125.png" alt="Current Apache event"/></a></li>
</ul>
</li>
<!-- Example:
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
-->
<li><a href="../../sitemap.xml">Sitemap</a></li>
<li><a href="../../feed.xml">Subscribe</a></li>
<li><a href="https://incubator.apache.org/guides/website.html" style="border:0px;" target="_target">
<img class="incubator-logo" src="../../logos/apache-incubator.png"/></a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="container">
<div class="page-header">
<h1>Apache Tamaya - Extension: Injection</h1>
</div>
<p><em>2019-11-17</em></p>
<p><div id="preamble">
<div class="sectionbody">
<!-- toc disabled -->
</div>
</div>
<div class="sect1">
<h2 id="Injection">Tamaya Injection (Extension Module)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Tamaya <em>Injection</em> is an extension module. Refer to the <a href="../extensions.html">extensions documentation</a> for further details.</p>
</div>
<div class="sect2">
<h3 id="_what_functionality_this_module_provides">What functionality this module provides ?</h3>
<div class="paragraph">
<p>Tamaya <em>Injection</em> provides functionality for injecting configured values into beans, or creating configuration
template instances.</p>
</div>
<div class="paragraph">
<p>Inversion of Control (aka IoC/the Hollywood Principle) has proven to be very useful and effective in avoiding boilerplate
code. In Java there are different frameworks available that all provide IoC mechanisms. Unfortunately IoC is not a
built-in language feature. So for a portable solution that works also in Java SE Tamaya itself has to provide the
according injection services. This module adds this functionality to Tamaya.</p>
</div>
</div>
<div class="sect2">
<h3 id="_compatibility">Compatibility</h3>
<div class="paragraph">
<p>The module is based on Java 7, so it can be used with Java 7 and beyond.</p>
</div>
</div>
<div class="sect2">
<h3 id="_installation">Installation</h3>
<div class="paragraph">
<p>Basically Tamaya&#8217;s injection API is deployed as API artifact:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.tamaya.ext&lt;/groupId&gt;
&lt;artifactId&gt;tamaya-injection-api&lt;/artifactId&gt;
&lt;version&gt;0.5-incubating-SNAPSHOT&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>To use injection with Java SE you must add the corresponding dependency to your module:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
&lt;groupId&gt;org.apache.tamaya.ext&lt;/groupId&gt;
&lt;artifactId&gt;tamaya-injection&lt;/artifactId&gt;
&lt;version&gt;0.5-incubating-SNAPSHOT&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Similarly there are other injection implementations available, targetig platforms such as</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="mod_spring.html">Spring, Spring Boot</a></p>
</li>
<li>
<p><a href="mod_CDI.html">Java EE/CDI</a></p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_core_concepts">Core Concepts</h3>
<div class="paragraph">
<p>Basically you annotate fields or methods in your beans with @Config to enable configuration injection. Tamaya
additionally defines further annotations that allo you to define additional aspects such as default values, custom
converters etc. The following example illustrates the basic functionality:</p>
</div>
<div class="listingblock">
<div class="title">Annotated Example Class</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">package foo.bar;
public class ConfiguredClass {
// resolved by default, using property name, class and package name: foo.bar.ConfiguredClass.testProperty
private String testProperty;
// Trying to resolve mutiple keys, with a default value, if none could be resolved
@Config({"a.b.c.key1","a.b.legacyKey",area1.key2"}, defaultValue="The current \\${JAVA_HOME} env property is ${env:JAVA_HOME}.")
String value1;
// Typical case
@Config("a.b.c.key2")
private int value2;
// resolved by default as foo.bar.ConfiguredClass.accessUrl
// Using a (default) String -&gt; URL converter
@Config(defaultValue="http://127.0.0.1:8080/res/api/v1/info.json")
private URL accessUrl;
// Config injection disabled for this property
@NoConfig
private Integer int1;
// Overriding the String -&gt; BigDecimal converter with a custom implementation.
@Config("BD")
@WithPropertyConverter(MyBigDecimalRoundingAdapter.class)
private BigDecimal bigNumber;
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When configuring data or configuration classes it is also possible to auto-inject the fields identified. For activating
this feature a class must be annotated with @ConfigAutoInject:</p>
</div>
<div class="listingblock">
<div class="title">An autoinjected bean class</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">package a.b;
@ConfigAutoInject
public final class Tenant {
private int id;
private String name;
private String description;
@NoConfig // prevents auto injection for this field
private String id2;
public int getId(){
return id;
}
public String getName(){
return name;
}
public String getDescription(){
return description;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>These examples do not show all possibilities provided. Configuring instance of these
class using Tamaya is very simple: Just pass the instance to Tamaya to let
Tamaya inject the configuration (or throw a ConfigException, if this is not possible):</p>
</div>
<div class="listingblock">
<div class="title">Configuring the ConfiguredClass Instance</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ConfiguredClass classInstance = new ConfiguredClass();
ConfigurationInjector.getInstance().configure(configuredClass);
Tenant tenant = new Tenant();
ConfigurationInjector.getInstance().configure(tenant);</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Configuration injection works similarly, when used with other integration modules, e.g. when Tamaya is used
with CDI, Spring or within an OSGi container. For further details refer also to the corresponding integration module&#8217;s
documentation.
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="_the_configurationinjector">The ConfigurationInjector</h4>
<div class="paragraph">
<p>The ConfigurationInjector interface provides methods that allow any kind of instances to be configured
by passing the instances to T ConfigurationInjector.getInstance().configure(T);. The classes passed
hereby must not be annotated with @Config for being configurable.</p>
</div>
</div>
<div class="sect3">
<h4 id="_accessing_supplier_instances">Accessing Supplier instances</h4>
<div class="paragraph">
<p>In many cases you want to create a supplier that simply creates instances that are correctly configured as defined
by the current context. This can be done using Suppliers:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Supplier&lt;Tenant&gt; configuredTenantSupplier = ConfigurationInjector.getInstance().getConfiguredSupplier(
new Supplier&lt;Tenant&gt;(){
public Tenant get(){
return new Tenant();
}
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>With Java 8 it&#8217;s even more simple:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Supplier&lt;Tenant&gt; configuredTenantSupplier = ConfigurationInjector.getInstance().getConfiguredSupplier(
Tenant::new);</code></pre>
</div>
</div>
<div class="paragraph">
<p>Hereby this annotation can be used in multiple ways and combined with other annotations such as
@WithLoadPolicy, @WithConfigOperator, @WithPropertyConverter.</p>
</div>
</div>
<div class="sect3">
<h4 id="_minimal_example">Minimal Example</h4>
<div class="paragraph">
<p>To illustrate the mechanism below the most simple variant of a configured class is given:</p>
</div>
<div class="listingblock">
<div class="title">Most simple configured class</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">pubic class ConfiguredItem{
@Config
private String aValue;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When this class is configured, e.g. by passing it to ConfigurationInjector.getInstance().configure(Object),
the following is happening:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The current valid Configuration is evaluated by calling Configuration cfg = Configuration.current();</p>
</li>
<li>
<p>The current property value (String) is evaluated by calling cfg.get("aValue"); for each possible key (mutliple
keys are possible).</p>
</li>
<li>
<p>if not successful, an error is thrown (ConfigException)</p>
</li>
<li>
<p>On success, since no type conversion is involved, the value is injected.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_the_annotations_in_detail">The Annotations in detail</h3>
<div class="sect3">
<h4 id="_using_config">Using <code>@Config</code></h4>
<div class="paragraph">
<p>This is the main annotation targeting a field in a class for configuration injection.</p>
</div>
<div class="sect4">
<h5 id="_evaluating_of_configuration_keys">Evaluating of <em>configuration keys</em></h5>
<div class="paragraph">
<p>By default Tamaya tries to determine configuration for each property of an instance
passed, using the following resolution policy:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Given a class a.b.MyClass and a field myField it would try to look up the
following keys:</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-listing" data-lang="listing">a.b.MyClass.myField
a.b.MyClass.my-field
MyClass.myField
MyClass.my-field
myField
my-field</code></pre>
</div>
</div>
<div class="paragraph">
<p>This behaviour can be adapted, e.g. by using the <code>@ConfigDefaultSections</code> annotation on the
declaring type:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@ConfigDefaultSections("a.b.c", "deprecated")
pubic class MyClass{
@Config
private String myField;
}</pre>
</div>
</div>
<div class="paragraph">
<p>This will result in a modified lookup chain as illustrated below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-listing" data-lang="listing">a.b.c.myField
a.b.c.my-field
deprecated.myField
deprecated.my-field</code></pre>
</div>
</div>
<div class="paragraph">
<p>This helps to reduce redundancy when referring to you configuration keys. Additionally
it is also possible to define absolute key entries, e.g.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>@ConfigDefaultSections("a.b.c")
pubic class MyClass{
@Config("myField" /* relative */, "[absolute.key]")
private String myField;
}</pre>
</div>
</div>
<div class="paragraph">
<p>This will result in a lookup chain as illustrated below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-listing" data-lang="listing">a.b.c.myField
absolute.key # default sections are ignored</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="_using_defaults">Using defaults</h5>
<div class="paragraph">
<p>In the next example we explicitly define the <em>default</em> property value:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">pubic class ConfiguredItem{
@Config(value={"aValue", "a.b.value","a.b.deprecated.value"}, defaultValue="${env:java.version}")
private String aValue;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_automatically_inject_all_items_using_configautoinject">Automatically inject all items using <code>@ConfigAutoInject</code></h4>
<div class="paragraph">
<p>Using <code>@ConfigAutoInject</code> allows you to automatically select all properties found for
configuration injection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@ConfigAutoInject
pubic class ConfiguredItem{
private transient int sum;
private String a;
private String b;
Private String c;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Adding the <code>@NoConfig</code> annotation prevents a field or method to be auto-injected from
configuration. This is especially useful, if a type is annotated as @ConfigAutoInject with auto-confiuration
turned on as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@NoConfig
private transient int sum;</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the fields a,b,c are configured, whereas the field sum is ignored regarding
configuration.</p>
</div>
</div>
<div class="sect3">
<h4 id="_adding_custom_operators_using_withconfigoperator">Adding custom operators using <code>@WithConfigOperator</code></h4>
<div class="paragraph">
<p>The @WithConfigOperator annotation allows you define a class of type ConfigOperator, to being applied
to the final Configuration, BEFORE the value is injected. This can be used for various use cases, e.g.
filtering or validating the visible properties for a certain use case.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">@WithConfigOperator(MyConfigView.class)
pubic class ConfiguredItem{
@Config
private String a;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_adding_custom_property_converters_using_withpropertyconverter">Adding custom property converters using <code>@WithPropertyConverter</code></h4>
<div class="paragraph">
<p>The @WithPropertyConverter annotation allows you to define a class of type PropertyConverter, to be applied
on a property configured to convert the String value to the expected injected type. This can be used for
various use cases, e.g. adding custom formats, config models, decryption.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">pubic class ConfiguredItem{
@WithPropertyConverter(MyPropertyConverter.class)
@Config
private String a;
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_inject_a_dynamicvalue">Inject a <code>DynamicValue</code></h4>
<div class="paragraph">
<p>Within this example we evaluate a dynamic value. This mechanism allows you to listen for configuration changes and to
commit new values exactly, when convenient for you.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">pubic class ConfiguredItem{
@Config(value={"aValue", "a.b.value","a.b.deprecated.value"}, defaultValue="${env:java.version}")
private DynamicValue aValue;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The DynamicValue provides you the following functionality:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public interface DynamicValue&lt;T&gt; {
T get();
T getNewValue();
T evaluateValue();
T commitAndGet();
void commit();
void discard();
boolean updateValue();
void setUpdatePolicy(UpdatePolicy updatePolicy);
UpdatePolicy getUpdatePolicy();
void addListener(PropertyChangeListener l);
void removeListener(PropertyChangeListener l);
boolean isPresent();
T orElse(T other);
T orElseGet(ConfiguredItemSupplier&lt;? extends T&gt; other);
&lt;X extends Throwable&gt; T orElseThrow(ConfiguredItemSupplier&lt;? extends X&gt; exceptionSupplier) throws X;
}
public enum UpdatePolicy{
IMMEDIATE,
EXPLICIT,
NEVER,
LOG_AND_DISCARD
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Summarizing DynamicValue looks somehow similar to the new Optional class added with Java 8. It provides
a wrapper class around a configured instance. Additionally this class provides functionality that gives
active control, to manage a configured value based on a +LoadingPolicy:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>IMMEDIATE means that when the configuration system detects a change on the underlying value, the new value
is automatically applied without any further notice.</p>
</li>
<li>
<p>EXPLICIT means that a new configuration value is signalled by setting the newValue property. if getNewValue()
returns a non null value, the new value can be applied by calling commit(). You can always access the newest value,
hereby implicitly applying it, by accessing it via commitAndGet(). Also it is possible ti ignore a change by calling
discard().</p>
</li>
<li>
<p>NEVER means the configured value is evaluated once and never updated. All changes are silently discarded.</p>
</li>
<li>
<p>LOG_AND_DISCARD similar to NEVER, but changes are logged before they are discarded.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Summarizing a DynamicValue allows you</p>
</div>
<div class="ulist">
<ul>
<li>
<p>to reload actively updates of configured values.</p>
</li>
<li>
<p>update implicitly or explicitly all changes on the value.</p>
</li>
<li>
<p>add listeners that observe changes of a certain value.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Dynamic values also allow on-the-fly reevaluation of the value by calling evaluateValue(). Hereby the value of the
instance is not changed.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_configuration_events">Configuration Events</h3>
<div class="paragraph">
<p>Similar to CDI Tamaya publishes Configuration events, when instances were configured. It depends on the effective
event backend in use, if and how events are published:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>when you have the CDI extension active events are published using the default CDI event mechanism.</p>
</li>
<li>
<p>in all other scenarios events are delegated to the tamaya-events module, if available,</p>
</li>
<li>
<p>if no event delegation is available no events are published.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The event published is very simple:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public interface ConfiguredType {
Class getType();
String getName();
Collection&lt;ConfiguredField&gt; getConfiguredFields();
Collection&lt;ConfiguredMethod&gt; getConfiguredMethods();
void configure(Object instance, Configuration config);
}
public interface ConfiguredField {
Class&lt;?&gt; getType();
Collection&lt;String&gt; getConfiguredKeys();
String getName();
String getSignature();
Field getAnnotatedField();
void configure(Object instance, Configuration config);
}
public interface ConfiguredMethod {
Collection&lt;String&gt; getConfiguredKeys();
Class&lt;?&gt;[] getParameterTypes();
Method getAnnotatedMethod();
String getName();
String getSignature();
void configure(Object instance, Configuration config);
}
----------------------------------------</code></pre>
</div>
</div>
</div>
</div>
</div></p>
<hr />
</div>
</div>
<div>
<div id="push"></div>
<div id="footer">
<div class="container">
<p class="muted credit">&copy; 2014-<span>2019</span> Apache Software Foundation | Mixed with <a href="https://getbootstrap.com/">Bootstrap v3.1.1</a>
| Baked with <a href="https://jbake.org">JBake <span>v2.6.4</span></a>
at <span>2019-11-17</span> |
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/tamayaconf">Follow @tamayaconf</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</p>
<p>
<b>Disclaimer</b>
Apache Tamaya (incubating) is an effort undergoing
incubation at
The Apache Software Foundation (ASF), sponsored by
the Apache Incubator. Incubation is required of
all newly accepted projects until a further review indicates
that the infrastructure, communications, and decision making
process have stabilized in a manner consistent with other
successful ASF projects. While incubation status is not
necessarily a reflection of the completeness or stability of
the code, it does indicate that the project has yet to
be fully endorsed by the ASF.<br />
Apache, Apache Tamaya, and the Apache Tamaya logo are registered trademarks or trademarks of The Apache Software Foundation in the U.S. and/or other countries.<br />
<a href="https://incubator.apache.org/guides/website.html" style="border:0px;" target="_target">
<img class="incubator-logo" src="../../logos/apache-incubator.png" style="height: 50px;"/>
</a>
</p>
</div>
</div>
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="../../js/jquery-1.11.1.min.js"></script>
<script src="../../js/bootstrap.min.js"></script>
<script src="../../js/prettify.js"></script>
</div>
</body>
</html>