| <!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’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"><dependency> |
| <groupId>org.apache.tamaya.ext</groupId> |
| <artifactId>tamaya-injection-api</artifactId> |
| <version>0.5-incubating-SNAPSHOT</version> |
| </dependency></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"><dependency> |
| <groupId>org.apache.tamaya.ext</groupId> |
| <artifactId>tamaya-injection</artifactId> |
| <version>0.5-incubating-SNAPSHOT</version> |
| </dependency></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 -> 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 -> 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’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<Tenant> configuredTenantSupplier = ConfigurationInjector.getInstance().getConfiguredSupplier( |
| new Supplier<Tenant>(){ |
| public Tenant get(){ |
| return new Tenant(); |
| } |
| });</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>With Java 8 it’s even more simple:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="prettyprint highlight"><code class="language-java" data-lang="java">Supplier<Tenant> 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<T> { |
| |
| 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<? extends T> other); |
| <X extends Throwable> T orElseThrow(ConfiguredItemSupplier<? extends X> 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<ConfiguredField> getConfiguredFields(); |
| Collection<ConfiguredMethod> getConfiguredMethods(); |
| void configure(Object instance, Configuration config); |
| } |
| |
| |
| public interface ConfiguredField { |
| Class<?> getType(); |
| Collection<String> getConfiguredKeys(); |
| String getName(); |
| String getSignature(); |
| Field getAnnotatedField(); |
| void configure(Object instance, Configuration config); |
| } |
| |
| public interface ConfiguredMethod { |
| Collection<String> getConfiguredKeys(); |
| Class<?>[] 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">© 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> |