You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by an...@apache.org on 2015/01/03 12:59:13 UTC

[04/27] incubator-tamaya git commit: TAMAYA-19: Reorganized dormant part for better focus of future discussions.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/modules/metamodels/simple/src/main/resources/META-INF/services/org.apache.tamaya.core.spi.ConfigurationProviderSpi
----------------------------------------------------------------------
diff --git a/dormant/modules/metamodels/simple/src/main/resources/META-INF/services/org.apache.tamaya.core.spi.ConfigurationProviderSpi b/dormant/modules/metamodels/simple/src/main/resources/META-INF/services/org.apache.tamaya.core.spi.ConfigurationProviderSpi
deleted file mode 100644
index b3a2634..0000000
--- a/dormant/modules/metamodels/simple/src/main/resources/META-INF/services/org.apache.tamaya.core.spi.ConfigurationProviderSpi
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy current the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-org.apache.tamaya.metamodel.simple.SimpleConfigProvider
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/dormant/modules/pom.xml
----------------------------------------------------------------------
diff --git a/dormant/modules/pom.xml b/dormant/modules/pom.xml
deleted file mode 100644
index e012023..0000000
--- a/dormant/modules/pom.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<!-- 
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy current the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.tamaya</groupId>
-        <artifactId>tamaya-all</artifactId>
-        <version>0.1-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-    <artifactId>tamaya-ext-all</artifactId>
-    <groupId>org.apache.tamaya.ext</groupId>
-    <name>Apache Tamaya Modules</name>
-    <packaging>pom</packaging>
-
-    <properties>
-        <github.global.server>github</github.global.server>
-        <jdkVersion>1.8</jdkVersion>
-        <maven.compile.targetLevel>${jdkVersion}</maven.compile.targetLevel>
-        <maven.compile.sourceLevel>${jdkVersion}</maven.compile.sourceLevel>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.tamaya</groupId>
-            <artifactId>tamaya-core</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.openejb</groupId>
-            <artifactId>mbean-annotation-api</artifactId>
-            <version>4.7.1</version>
-        </dependency>
-    </dependencies>
-
-    <modules>
-        <module>metamodels</module>
-        <module>integration</module>
-        <!-- <module>environment</module> -->
-    </modules>
-
-</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/pom.xml
----------------------------------------------------------------------
diff --git a/modules/injection/pom.xml b/modules/injection/pom.xml
new file mode 100644
index 0000000..90f0b59
--- /dev/null
+++ b/modules/injection/pom.xml
@@ -0,0 +1,40 @@
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy current the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.tamaya.integration</groupId>
+        <artifactId>tamaya-extensions-all</artifactId>
+        <version>0.2-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <artifactId>tamaya-injection</artifactId>
+    <name>Apache Tamaya Injection Support</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tamaya</groupId>
+            <artifactId>tamaya-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperties.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperties.java b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperties.java
new file mode 100644
index 0000000..e1d773d
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperties.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation container to enable injection current multiple {@link org.apache.tamaya.annotation.ConfiguredProperty}
+ * annotations. Hereby the ordering current annotations imply the defaulting. The first keys that
+ * could be resolved successfully in the chain current annotations will be used.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface ConfiguredProperties {
+
+    /**
+     * Get the different configuration keys to be looked up, in order current precedence. The first non null keys
+     * found will be used.
+     */
+    ConfiguredProperty[] value() default {};
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperty.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperty.java b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperty.java
new file mode 100644
index 0000000..21d4e3a
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/ConfiguredProperty.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation to enable injection current a configured property or define the returned data for
+ * a configuration template method. Hereby this annotation can be used in multiple ways and combined
+ * with other annotations such as {@link org.apache.tamaya.annotation.DefaultValue},
+ * {@link org.apache.tamaya.annotation.WithLoadPolicy}, {@link org.apache.tamaya.annotation.WithConfig},
+ * {@link org.apache.tamaya.annotation.WithConfigOperator}, {@link WithPropertyAdapter}.
+ *
+ * Below the most simple variant current a configured class is given:
+ * {@code
+ * pubic class ConfiguredItem{
+ *
+ *   @ConfiguredProperty
+ *   private String aValue;
+ * }
+ * When this class is configured, e.g. by passing it to {@link org.apache.tamaya.Configuration#configure(Object)},
+ * the following is happening:
+ * <ul>
+ *     <li>The current valid Configuration is evaluated by calling {@code Configuration cfg = Configuration.current();}</li>
+ *     <li>The current property String keys is evaluated by calling {@code cfg.get("aValue");}</li>
+ *     <li>if not successful, an error is thrown ({@link org.apache.tamaya.ConfigException}.</li>
+ *     <li>On success, since no type conversion is involved, the keys is injected.</li>
+ *     <li>The configured bean is registered as a weak change listener in the config system's underlying
+ *     configuration, so future config changes can be propagated (controlled by {@link org.apache.tamaya.annotation.WithLoadPolicy}
+ *     annotations).</li>
+ * </ul>
+ *
+ * In the next example we explicitly define the property keys:
+ * {@code
+ * pubic class ConfiguredItem{
+ *
+ *   @ConfiguredProperty
+ *   @ConfiguredProperty({"a.b.value", "a.b.deprecated.keys", "${env:java.version}"})
+ *   @ConfiguredProperty(configuration={"a", "b"}
+ *   @ConfiguredProperty(configuration={"a", "b", keys={"a.b.keys", "a.b.deprecated.keys", "${env:java.version}"}}
+ *   private String aValue;
+ * }
+ *
+ * Within this example we evaluate multiple possible keys. Evaluation is aborted if a key could be successfully
+ * resolved. Hereby the ordering current the annotations define the ordering current resolution, so in the example above
+ * resolution equals to {@code "aValue", "a.b.keys", "a.b.deprecated.keys"}. If no keys could be read
+ * fromMap the configuration, it uses the keys fromMap the {@code DefaultValue} annotation. Interesting here
+ * is that this keys is not static, it is evaluated by calling
+ * {@link org.apache.tamaya.Configuration#evaluateValue(String, org.apache.tamaya.Configuration...)}.
+ */
+@Repeatable(ConfiguredProperties.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface ConfiguredProperty {
+
+    /**
+     * Annotation to reference an explicit {@link org.apache.tamaya.Configuration} to be used to
+     * resolve the required properties. the configured keys is passed to {@code Configuration.current(String)}
+     * to evaluate the required configuration required.
+     * @return the configurations to be looked up for the given keys.
+     */
+    String config() default "";
+
+    /**
+     * Get the property names to be used. Hereby the first non null keys evaluated is injected as property keys.
+     *
+     * @return the property names, not null. If missing the field or method name being injected is used by default.
+     */
+    String[] keys() default {};
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultAreas.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultAreas.java b/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultAreas.java
new file mode 100644
index 0000000..63ea137
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultAreas.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to control injection and resolution current a configured bean. The configuration keys
+ * to be resolved are basically determined by the {@link org.apache.tamaya.annotation.ConfiguredProperty}
+ * annotation(s). Nevertheless these annotations can also have relative key names. This annotation allows
+ * to define a configuration area that is prefixed to all relative configuration keys within the
+ * corresponding class/template interface.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE })
+public @interface DefaultAreas {
+
+    /**
+     * Allows to declare an operator that should be applied before injecting values into the bean.
+     * @return the operator class to be used.
+     */
+    String[] value();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultValue.java b/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultValue.java
new file mode 100644
index 0000000..c4b2e3a
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/DefaultValue.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define a default keys to be returned, when no configured keys could be
+ * determined for a property/template accessor. The keys hereby can also contain a
+ * dynamic expression that is evaluated by the configuration system.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface DefaultValue {
+
+    /**
+     * The default keys to be injected, if no such configuration entry was found. If keys was found and no default
+     * is defined, it is handled as a deployment error.
+     */
+    String value() default "";
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/DynamicValue.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/DynamicValue.java b/modules/injection/src/main/java/org/apache/tamaya/inject/DynamicValue.java
new file mode 100644
index 0000000..b8e0cf5
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/DynamicValue.java
@@ -0,0 +1,500 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya;
+
+import java.beans.PropertyChangeEvent;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.ref.WeakReference;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+/**
+ * A accessor for a single configured value. This can be used to support values that may change during runtime, reconfigured or
+ * final. Hereby external code (could be Tamaya configuration listners or client code), can set a new value. Depending on the
+ * {@link org.apache.tamaya.DynamicValue.UpdatePolicy} the new value is immedeately active or it requires an active commit
+ * by client code. Similarly an instance also can ignore all later changes to the value.
+ * <h3>Implementation Details</h3>
+ * This class is
+ * <ul>
+ *     <li>Serializable, when also the item stored is serializable</li>
+ *     <li>Thread safe</li>
+ * </ul>
+ */
+public final class DynamicValue<T> implements Serializable{
+
+    /**
+     * Policy to control how new values are applied to this instance.
+     */
+    enum UpdatePolicy{
+        /** New values are applied immedately and registered listeners are informed about the change. */
+        IMMEDIATE,
+        /** New values or not applied, but stored in the newValue property. Explcit call to #commit
+         of #commitAndGet are required to accept the change and inform the listeners about the change.
+         */
+        EXPLCIT,
+        /**
+         * New values are always immedately discarded.
+         */
+        NEVER,
+        /**
+         * Changes are logged before the are discarded.
+         */
+        LOG_AND_DISCARD
+    }
+
+
+    /** The property name of the entry. */
+    private String propertyName;
+    /**
+     * Policy that defines how new values are applied, be default it is applied initially once, but never updated anymore.
+     */
+    private UpdatePolicy updatePolicy = UpdatePolicy.NEVER;
+    /** The current value, never null. */
+    private transient Optional<T> value;
+    /** The new value, or null. */
+    private transient Optional<T> newValue;
+    /** List of listeners that listen for changes. */
+    private transient WeakList<Consumer<PropertyChangeEvent>> listeners;
+
+    /**
+     * Returns an empty {@code Optional} instance.  No value is present for this
+     * Optional.
+     *
+     * @apiNote Though it may be tempting to do so, avoid testing if an object
+     * is empty by comparing with {@code ==} against instances returned by
+     * {@code Option.empty()}. There is no guarantee that it is a singleton.
+     * Instead, use {@link #isPresent()}.
+     *
+     * @param <T> Type of the non-existent value
+     * @return an empty {@code Optional}
+     */
+    public static <T> DynamicValue<T> empty(String propertyName) {
+        DynamicValue v = new DynamicValue<T>(propertyName, null);
+        return v;
+    }
+
+    /**
+     * Constructor.
+     * @param propertyName the name of the value in the format {@code <configName>:<propertyName>}.</config>
+     * @param item the initial value.
+     */
+    private DynamicValue(String propertyName, Optional<T> item){
+        this.propertyName = Objects.requireNonNull(propertyName);
+        this.value = item;
+    }
+
+    /**
+     * Creates a new instance.
+     * @param propertyName the name of the value in the format {@code <configName>:<propertyName>}.</config>
+     * @param value the initial value, not null.
+     * @param <T> the type
+     * @return a new instance, never null
+     */
+    public static <T> DynamicValue<T> of(String propertyName, T value){
+        return new DynamicValue(propertyName, Optional.of(value));
+    }
+
+    /**
+     * Creates a new instance.
+     * @param propertyName the name of the value in the format {@code <configName>:<propertyName>}.</config>
+     * @param value the initial value
+     * @param <T> the target type.
+     * @return a new instance, never null
+     */
+    public static <T> DynamicValue<T> ofNullable(String propertyName, T value){
+        return value == null ? empty(propertyName) : of(propertyName, value);
+    }
+
+    /**
+     * Performs a commit, if necessary and returns the current value.
+     * otherwise throws {@code ConfigException}.
+     *
+     * @return the non-null value held by this {@code Optional}
+     * @throws org.apache.tamaya.ConfigException if there is no value present
+     *
+     * @see DynamicValue#isPresent()
+     */
+    public T commitAndGet(){
+        commit();
+        return get();
+    }
+
+    /**
+     * Commits a new value that has not been committed yet, make it the new value of the instance. On change any registered listeners will be triggered.
+     */
+    public void commit(){
+        synchronized (value){
+            if(newValue!=null){
+                PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, value.orElse(null), newValue.orElse(null));
+                value = newValue;
+                newValue = null;
+                for(Consumer<PropertyChangeEvent> consumer: listeners.get()){
+                    consumer.accept(evt);
+                }
+            }
+        }
+    }
+
+    /**
+     * Discards a new value that was published. No listeners will be informed.
+     */
+    public void discard(){
+        newValue = null;
+    }
+
+
+
+    /**
+     * Access the {@link UpdatePolicy} used for updating this value.
+     * @return the update policy, never null.
+     */
+    public UpdatePolicy getUpdatePolicy() {
+        return updatePolicy;
+    }
+
+    /**
+     * Add a listener to be called as weak reference, when this value has been changed.
+     * @param l the listner, not null
+     */
+    public void addListener(Consumer<PropertyChangeEvent> l) {
+        if(listeners==null){
+            listeners = new WeakList<>();
+        }
+        listeners.add(l);
+    }
+
+    /**
+     * Removes a listener to be called, when this value has been changed.
+     * @param l the listner to be removed, not null
+     */
+    public void removeListener(Consumer<PropertyChangeEvent> l) {
+        if(listeners!=null){
+            listeners.remove(l);
+        }
+    }
+
+    /**
+     * If a value is present in this {@code ConfiguredValue}, returns the value,
+     * otherwise throws {@code ConfigException}.
+     *
+     * @return the non-null value held by this {@code Optional}
+     * @throws org.apache.tamaya.ConfigException if there is no value present
+     *
+     * @see DynamicValue#isPresent()
+     */
+    public T get() {
+        return value.get();
+    }
+
+    /**
+     * Method to apply a new value. Depending on the {@link  org.apache.tamaya.DynamicValue.UpdatePolicy}
+     * the value is immediately or deferred visible (or it may even be ignored completely).
+     * @param newValue the new value, may also be null.
+     */
+    public void setNewValue(T newValue){
+        switch(this.updatePolicy){
+            case IMMEDIATE:
+                this.newValue = Optional.ofNullable(newValue);
+                commit();
+                break;
+            case EXPLCIT:
+                this.newValue = Optional.ofNullable(newValue);
+                break;
+            case LOG_AND_DISCARD:
+                Logger.getLogger(getClass().getName()).info("Discard change on " + this + ", newValue="+newValue);
+                this.newValue = null;
+                break;
+            case NEVER:
+                this.newValue = null;
+                break;
+        }
+
+    }
+
+    /**
+     * Sets a new {@link org.apache.tamaya.DynamicValue.UpdatePolicy}.
+     * @param updatePolicy the new policy, not null.
+     */
+    public void setUpdatePolicy(UpdatePolicy updatePolicy){
+        this.updatePolicy = Objects.requireNonNull(updatePolicy);
+    }
+
+    /**
+     * Access a new value that has not yet been committed.
+     * @return the uncommitted new value, or null.
+     */
+    public T getNewValue(){
+        Optional<T> nv = newValue;
+        if(nv!=null){
+            return nv.orElse(null);
+        }
+        return null;
+    }
+
+    /**
+     * Return {@code true} if there is a value present, otherwise {@code false}.
+     *
+     * @return {@code true} if there is a value present, otherwise {@code false}
+     */
+    public boolean isPresent() {
+        return value.isPresent();
+    }
+
+    /**
+     * If a value is present, invoke the specified consumer with the value,
+     * otherwise do nothing.
+     *
+     * @param consumer block to be executed if a value is present
+     * @throws NullPointerException if value is present and {@code consumer} is
+     * null
+     */
+    public void ifPresent(Consumer<? super T> consumer) {
+        value.ifPresent(consumer);
+    }
+
+    /**
+     * If a value is present, and the value matches the given predicate,
+     * return an {@code Optional} describing the value, otherwise return an
+     * empty {@code Optional}.
+     *
+     * @param predicate a predicate to apply to the value, if present
+     * @return an {@code Optional} describing the value of this {@code Optional}
+     * if a value is present and the value matches the given predicate,
+     * otherwise an empty {@code Optional}
+     * @throws NullPointerException if the predicate is null
+     */
+    public DynamicValue<T> filter(Predicate<? super T> predicate) {
+        Objects.requireNonNull(predicate);
+        if (!isPresent())
+            return this;
+        else
+            return predicate.test(value.get()) ? this : empty(propertyName);
+    }
+
+    /**
+     * If a value is present, apply the provided mapping function to it,
+     * and if the result is non-null, return an {@code Optional} describing the
+     * result.  Otherwise return an empty {@code Optional}.
+     *
+     * @apiNote This method supports post-processing on optional values, without
+     * the need to explicitly check for a return status.  For example, the
+     * following code traverses a stream of file names, selects one that has
+     * not yet been processed, and then opens that file, returning an
+     * {@code Optional<FileInputStream>}:
+     *
+     * <pre>{@code
+     *     Optional<FileInputStream> fis =
+     *         names.stream().filter(name -> !isProcessedYet(name))
+     *                       .findFirst()
+     *                       .map(name -> new FileInputStream(name));
+     * }</pre>
+     *
+     * Here, {@code findFirst} returns an {@code Optional<String>}, and then
+     * {@code map} returns an {@code Optional<FileInputStream>} for the desired
+     * file if one exists.
+     *
+     * @param <U> The type of the result of the mapping function
+     * @param mapper a mapping function to apply to the value, if present
+     * @return an {@code Optional} describing the result of applying a mapping
+     * function to the value of this {@code Optional}, if a value is present,
+     * otherwise an empty {@code Optional}
+     * @throws NullPointerException if the mapping function is null
+     */
+    public <U> DynamicValue<U> map(Function<? super T, ? extends U> mapper) {
+        Objects.requireNonNull(mapper);
+        if (!isPresent())
+            return empty(propertyName);
+        else {
+            return DynamicValue.ofNullable(propertyName, mapper.apply(value.get()));
+        }
+    }
+
+    /**
+     * If a value is present, apply the provided {@code Optional}-bearing
+     * mapping function to it, return that result, otherwise return an empty
+     * {@code Optional}.  This method is similar to {@link #map(Function)},
+     * but the provided mapper is one whose result is already an {@code Optional},
+     * and if invoked, {@code flatMap} does not wrap it with an additional
+     * {@code Optional}.
+     *
+     * @param <U> The type parameter to the {@code Optional} returned by
+     * @param mapper a mapping function to apply to the value, if present
+     *           the mapping function
+     * @return the result of applying an {@code Optional}-bearing mapping
+     * function to the value of this {@code Optional}, if a value is present,
+     * otherwise an empty {@code Optional}
+     * @throws NullPointerException if the mapping function is null or returns
+     * a null result
+     */
+    public <U> DynamicValue<U> flatMap(Function<? super T, DynamicValue<U>> mapper) {
+        Objects.requireNonNull(mapper);
+        if (!isPresent())
+            return empty(propertyName);
+        else {
+            return Objects.requireNonNull(mapper.apply(value.get()));
+        }
+    }
+
+    /**
+     * Return the value if present, otherwise return {@code other}.
+     *
+     * @param other the value to be returned if there is no value present, may
+     * be null
+     * @return the value, if present, otherwise {@code other}
+     */
+    public T orElse(T other) {
+        return value.orElse(other);
+    }
+
+    /**
+     * Return the value if present, otherwise invoke {@code other} and return
+     * the result of that invocation.
+     *
+     * @param other a {@code Supplier} whose result is returned if no value
+     * is present
+     * @return the value if present otherwise the result of {@code other.get()}
+     * @throws NullPointerException if value is not present and {@code other} is
+     * null
+     */
+    public T orElseGet(Supplier<? extends T> other) {
+        return value.orElseGet(other);
+    }
+
+    /**
+     * Return the contained value, if present, otherwise throw an exception
+     * to be created by the provided supplier.
+     *
+     * @apiNote A method reference to the exception constructor with an empty
+     * argument list can be used as the supplier. For example,
+     * {@code IllegalStateException::new}
+     *
+     * @param <X> Type of the exception to be thrown
+     * @param exceptionSupplier The supplier which will return the exception to
+     * be thrown
+     * @return the present value
+     * @throws X if there is no value present
+     * @throws NullPointerException if no value is present and
+     * {@code exceptionSupplier} is null
+     */
+    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
+        return value.orElseThrow(exceptionSupplier);
+    }
+
+    /**
+     * Converts the instance to an {@link java.util.Optional} instance.
+     * @return the corresponding Optional value.
+     */
+    public Optional<T> toOptional(){
+        return value;
+    }
+
+    /**
+     * Serialization implementation that strips away the non serializable Optional part.
+     * @param oos the output stream
+     * @throws IOException if serialization fails.
+     */
+    private void writeObject(ObjectOutputStream oos)throws IOException {
+        oos.writeObject(updatePolicy);
+        if(isPresent()) {
+            oos.writeObject(this.value.get());
+        }
+        else{
+            oos.writeObject(null);
+        }
+    }
+
+    /**
+     * Reads an instance from the input stream.
+     * @param ois the object input stream
+     * @throws IOException if deserialization fails.
+     * @throws ClassNotFoundException
+     */
+    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+        this.updatePolicy = (UpdatePolicy)ois.readObject();
+        if(isPresent()) {
+            this.value = Optional.of((T) ois.readObject());
+        }
+        newValue = null;
+    }
+
+
+    /**
+     * Simple helper that allows keeping the listeners registered as weak references, hereby avoiding any
+     * memory leaks.
+     * @param <T> the type
+     */
+    private class WeakList<T>{
+        List<WeakReference<T>> refs = new LinkedList<>();
+
+        /**
+         * Adds a new instance.
+         * @param t the new instance, not null.
+         */
+        void add(T t){
+            refs.add(new WeakReference(t));
+        }
+
+        /**
+         * Removes a instance.
+         * @param t the instance to be removed.
+         */
+        void remove(T t){
+            synchronized (refs){
+                for(Iterator<WeakReference<T>> iterator = refs.iterator();iterator.hasNext();){
+                    WeakReference<T> ref = iterator.next();
+                    T instance = ref.get();
+                    if(instance==null || instance == t){
+                        iterator.remove();
+                        break;
+                    }
+                }
+            }
+        }
+
+
+        /**
+         * Access a list (copy) of the current instances that were not discarded by the GC.
+         * @return the list of accessible items.
+         */
+        public List<T> get() {
+            synchronized (refs) {
+                List<T> res = new ArrayList<>();
+                for (Iterator<WeakReference<T>> iterator = refs.iterator(); iterator.hasNext(); ) {
+                    WeakReference<T> ref = iterator.next();
+                    T instance = ref.get();
+                    if(instance==null){
+                        iterator.remove();
+                    }
+                    else{
+                        res.add(instance);
+                    }
+                }
+                return res;
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/LoadPolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/LoadPolicy.java b/modules/injection/src/main/java/org/apache/tamaya/inject/LoadPolicy.java
new file mode 100644
index 0000000..116a2c1
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/LoadPolicy.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+/**
+ * Available policies that describe how changes affecting configured values are published/reinjected.
+ * The policy also affects the cases were any configured listeners/listener methods are called for
+ * propagation current configuration changes.
+ */
+public enum LoadPolicy {
+    /**
+     * The configuration keys is evaluated once, when the owning component is loaded/configured, but never updated later.
+     */
+    INITIAL,
+    /**
+     * The configuration keys is evaluated exactly once on its first use lazily, but never updated later.
+     * This feature is not applicable on field injection, but only on configuration template methods.
+     */
+    LAZY,
+    /**
+     * The configuration keys is evaluated once, when the owning component is loaded/configured.
+     * Later changes on this configuration entry will be reinjected/updated and additionally triggered
+     * as {@link java.beans.PropertyChangeEvent}.
+     */
+    MANAGED,
+    /**
+     * The configuration keys is evaluated once, when the owning component is loaded/configured.
+     * Later changes on this configuration entry will be reinjected/updated, but no {@link java.beans.PropertyChangeEvent}
+     * will be triggered.
+     */
+    SILENT
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/NoConfig.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/NoConfig.java b/modules/injection/src/main/java/org/apache/tamaya/inject/NoConfig.java
new file mode 100644
index 0000000..845ec4c
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/NoConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * This is a small marker annotations to inform Tamaya that the annotated element should never be injected with
+ * configured data. This is useful because by default Tamaya tries to lookup and inject configuration also by
+ * using property or method names without annotations. With that annotation none of these will be happen.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface NoConfig {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/ObservesConfigChange.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/ObservesConfigChange.java b/modules/injection/src/main/java/org/apache/tamaya/inject/ObservesConfigChange.java
new file mode 100644
index 0000000..ef92b25
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/ObservesConfigChange.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to annotate a method on a class to be informed on config changes.
+ * The exact behaviour, when configuration change events are sent can be configured
+ * on each configured property/method by adding the {@link org.apache.tamaya.annotation.WithLoadPolicy}
+ * annotation. By default listeners are informed on all changes of configurations that were used as
+ * input configurations for configuring a class/instance. Additionally {@link org.apache.tamaya.annotation.ConfiguredProperty}
+ * annotations can be added that allows to constrain changes to some limited properties.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.METHOD })
+public @interface ObservesConfigChange {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/WithConfigOperator.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/WithConfigOperator.java b/modules/injection/src/main/java/org/apache/tamaya/inject/WithConfigOperator.java
new file mode 100644
index 0000000..9f6c4f5
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/WithConfigOperator.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import org.apache.tamaya.Configuration;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.function.UnaryOperator;
+
+/**
+ * Annotation to define an configuration operator to be used before accessing a configured keys.
+ * This allows filtering current configuration, e.g. for realizing views or ensuring security
+ * constraints.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
+public @interface WithConfigOperator {
+
+    /**
+     * Define a custom adapter that should be used to adapt the configuration entry injected. This overrides any
+     * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+     * registered, it is handled as a deployment error.
+     */
+    Class<? extends UnaryOperator<Configuration>> value();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/WithLoadPolicy.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/WithLoadPolicy.java b/modules/injection/src/main/java/org/apache/tamaya/inject/WithLoadPolicy.java
new file mode 100644
index 0000000..e469f5a
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/WithLoadPolicy.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define how config changes are handled for a type or per property/template method.
+ * @see org.apache.tamaya.annotation.LoadPolicy
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
+public @interface WithLoadPolicy {
+
+    /**
+     * The load policy to be used. If this annotation is present a load policy must be defined.
+     * @return The load policy to be used, not null.
+     */
+    LoadPolicy value();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/WithPropertyAdapter.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/WithPropertyAdapter.java b/modules/injection/src/main/java/org/apache/tamaya/inject/WithPropertyAdapter.java
new file mode 100644
index 0000000..fa9cfdf
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/WithPropertyAdapter.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.annotation;
+
+import org.apache.tamaya.PropertyAdapter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to define a type adapter to be used before injecting a configured keys, or for applying changes.
+ * This will override any other adapter for performing the type conversion before
+ * injecting the field keys.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.METHOD })
+public @interface WithPropertyAdapter {
+
+    /**
+     * Define a custom adapter or codec that should be used to adapt the configuration entry injected. This overrides any
+     * general org.apache.tamaya.core.internal registered. If no adapter is defined (default) and no corresponding adapter is
+     * registered, it is handled as a deployment error.
+     */
+    @SuppressWarnings("rawtypes")
+	Class<? extends PropertyAdapter> value();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigChangeCallbackMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigChangeCallbackMethod.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigChangeCallbackMethod.java
new file mode 100644
index 0000000..f929f8e
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigChangeCallbackMethod.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import org.apache.tamaya.core.properties.PropertyChangeSet;
+import org.apache.tamaya.Configuration;
+
+import java.lang.reflect.Method;
+import java.util.Optional;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class holds a method object that is annotated to be a callback method to be called on configuration
+ * changes.
+ */
+public final class ConfigChangeCallbackMethod {
+
+    private static final Logger LOG = Logger.getLogger(ConfigChangeCallbackMethod.class.getName());
+
+    private Method callbackMethod;
+
+    public ConfigChangeCallbackMethod(Method callbackMethod) {
+        this.callbackMethod = Optional.of(callbackMethod).filter(
+                (m) -> void.class.equals(m.getReturnType()) &&
+                        m.getParameterCount() == 1 &&
+                        m.getParameterTypes()[0].equals(PropertyChangeSet.class)).get();
+    }
+
+    public Consumer<PropertyChangeSet> createConsumer(Object instance, Configuration... configurations){
+        // TODO consider also environment !
+        return event -> {
+            for(Configuration cfg:configurations){
+                if(event.getPropertySource().getName().equals(cfg.getName())){
+                    return;
+                }
+            }
+            call(instance, event);
+        };
+    }
+
+    public void call(Object instance, PropertyChangeSet configChangeEvent) {
+        try {
+            callbackMethod.setAccessible(true);
+            callbackMethod.invoke(instance, configChangeEvent);
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE, e, () -> "Error calling ConfigChange callback method " + callbackMethod.getDeclaringClass().getName() + '.' + callbackMethod.getName() + " on " + instance);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
new file mode 100644
index 0000000..ff2c309
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigTemplateInvocationHandler.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.core.internal.inject.ConfiguredType;
+import org.apache.tamaya.core.internal.inject.InjectionUtils;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Objects;
+
+/**
+ * Invocation handler that handles request against a configuration template.
+ */
+public final class ConfigTemplateInvocationHandler implements InvocationHandler {
+
+    /*
+    TODO
+    the given method (in case of a template) can use different caching strategies:
+    1) no caching (always evaluate the values completely) - slow.
+    2) instance caching (a cache per instance).
+    3) classloader caching...
+    4) global shared cache.
+     */
+
+
+    /**
+     * Any overriding configurations.
+     */
+    private Configuration[] configurations;
+    /**
+     * The configured type.
+     */
+    private ConfiguredType type;
+
+    /**
+     * Creates a new handler instance.
+     * @param type           the target type, not null.
+     * @param configurations overriding configurations to be used for evaluating the values for injection into {@code instance}, not null.
+     *                       If no such config is passed, the default configurationa provided by the current
+     *                       registered providers are used.
+     */
+    public ConfigTemplateInvocationHandler(Class<?> type, Configuration... configurations) {
+        this.configurations = Objects.requireNonNull(configurations).clone();
+        this.type = new ConfiguredType(Objects.requireNonNull(type));
+        if (!type.isInterface()) {
+            throw new IllegalArgumentException("Can only proxy interfaces as configuration templates.");
+        }
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if ("toString".equals(method.getName())) {
+            return "Configured Proxy -> " + this.type.getType().getName();
+        }
+        String configValue = InjectionUtils.getConfigValue(method, configurations);
+        return InjectionUtils.adaptValue(method, method.getReturnType(), configValue);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigurationInjector.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigurationInjector.java
new file mode 100644
index 0000000..8a51375
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfigurationInjector.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import org.apache.tamaya.Configuration;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Simple injector singleton that also registers instances configured using weak references.
+ */
+@SuppressWarnings("rawtypes")
+public final class ConfigurationInjector {
+
+    private static final ConfigurationInjector INSTANCE = new ConfigurationInjector();
+
+	private Map<Class, ConfiguredType> configuredTypes = new ConcurrentHashMap<>();
+
+    /**
+     * Extract the configuration annotation config and registers it per class, for later reuse.
+     * @param type the type to be configured.
+     * @return the configured type registered.
+     */
+    public static ConfiguredType registerType(Class<?> type){
+        return INSTANCE.configuredTypes.computeIfAbsent(type, ConfiguredType::new);
+    }
+
+    /**
+     * Configured the current instance and reigsterd necessary listener to forward config change events as
+     * defined by the current annotations in place.
+     * @param instance the instance to be configured
+     * @param configurations Configuration instances that replace configuration served by services. This allows
+     *                       more easily testing and adaption.
+     */
+    public static void configure(Object instance, Configuration... configurations){
+        Class type = Objects.requireNonNull(instance).getClass();
+        ConfiguredType configuredType = registerType(type);
+        Objects.requireNonNull(configuredType).configure(instance, configurations);
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredField.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredField.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredField.java
new file mode 100644
index 0000000..51c3904
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredField.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import java.lang.reflect.Field;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.annotation.ConfiguredProperties;
+import org.apache.tamaya.annotation.ConfiguredProperty;
+import org.apache.tamaya.annotation.DefaultAreas;
+import org.apache.tamaya.core.internal.Utils;
+
+/**
+ * Small class that contains and manages all information anc access to a configured field and a concrete instance current
+ * it (referenced by a weak reference). It also implements all aspects current keys filtering, converting any applying the
+ * final keys by reflection.
+ */
+public class ConfiguredField {
+
+
+    /**
+     * The configured field instance.
+     */
+    private Field annotatedField;
+
+    /**
+     * Models a configured field and provides mechanisms for injection.
+     *
+     * @param field the field instance.
+     */
+    public ConfiguredField(Field field) {
+        Objects.requireNonNull(field);
+        this.annotatedField = field;
+    }
+
+    /**
+     * Evaluate the initial keys fromMap the configuration and applyChanges it to the field.
+     *
+     * @param target the target instance.
+     * @param configurations Configuration instances that replace configuration served by services. This allows
+     *                       more easily testing and adaption.
+     * @throws ConfigException if evaluation or conversion failed.
+     */
+    public void applyInitialValue(Object target, Configuration... configurations) throws ConfigException {
+        String configValue = InjectionUtils.getConfigValue(this.annotatedField, configurations);
+        applyValue(target, configValue, false, configurations);
+    }
+
+
+    /**
+     * This method reapplies a changed configuration keys to the field.
+     *
+     * @param target      the target instance, not null.
+     * @param configValue the new keys to be applied, null will trigger the evaluation current the configured default keys.
+     * @param resolve     set to true, if expression resolution should be applied on the keys passed.
+     * @throws ConfigException if the configuration required could not be resolved or converted.
+     */
+    public void applyValue(Object target, String configValue, boolean resolve, Configuration... configurations) throws ConfigException {
+        Objects.requireNonNull(target);
+        try {
+            if (resolve && configValue != null) {
+                // net step perform exression resolution, if any
+                configValue = Configuration.evaluateValue(configValue, configurations);
+            }
+            // Check for adapter/filter
+            Object value = InjectionUtils.adaptValue(this.annotatedField, this.annotatedField.getType(), configValue);
+            annotatedField.setAccessible(true);
+            annotatedField.set(target, value);
+        } catch (Exception e) {
+            throw new ConfigException("Failed to annotation configured field: " + this.annotatedField.getDeclaringClass()
+                    .getName() + '.' + annotatedField.getName(), e);
+        }
+    }
+
+
+    /**
+     * This method checks if the given (qualified) configuration key is referenced fromMap this field.
+     * This is useful to determine, if a key changed in a configuration should trigger any change events
+     * on the related instances.
+     *
+     * @param key the (qualified) configuration key, not null.
+     * @return true, if the key is referenced.
+     */
+    public boolean matchesKey(String configName, String key) {
+        Collection<ConfiguredProperty> configuredProperties = Utils.getAnnotations(this.annotatedField, ConfiguredProperty.class,
+                ConfiguredProperties.class );
+        for(ConfiguredProperty prop: configuredProperties){
+            String currentName = prop.config().trim();
+            if(currentName.isEmpty()){
+                if(!"default".equals(configName)){
+                    continue;
+                }
+            }
+            else if(!currentName.equals(configName)){
+                continue;
+            }
+            DefaultAreas areasAnnot = this.annotatedField.getDeclaringClass().getAnnotation(DefaultAreas.class);
+            List<String> keys = InjectionUtils.evaluateKeys(this.annotatedField, areasAnnot, prop);
+            if( keys.contains(key)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
new file mode 100644
index 0000000..90497ae
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredSetterMethod.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+import org.apache.tamaya.core.properties.PropertyChangeSet;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.annotation.*;
+import org.apache.tamaya.core.internal.Utils;
+
+/**
+ * Small class that contains and manages all information and access to a configured field and a concrete instance current
+ * it (referenced by a weak reference). It also implements all aspects current keys filtering, conversions any applying the
+ * final keys by reflection.
+ */
+public class ConfiguredSetterMethod {
+
+    /**
+     * The configured field instance.
+     */
+    private Method setterMethod;
+
+    /**
+     * Models a configured field and provides mechanisms for injection.
+     *
+     * @param method the method instance.
+     */
+    public ConfiguredSetterMethod(Method method) {
+        this.setterMethod = Optional.of(method).filter(
+                (m) -> void.class.equals(m.getReturnType()) &&
+                        m.getParameterCount() == 1).get();
+    }
+
+    public Consumer<PropertyChangeSet> createConsumer(Object instance, Configuration... configurations){
+        // TODO consider environment as well
+        return event -> {
+            for(Configuration cfg:configurations){
+                if(event.getPropertySource().getName().equals(cfg.getName())){
+                    // ignore these changes, since this config is overridden.
+                    return;
+                }
+            }
+            String configValue = InjectionUtils.getConfigValue(setterMethod, configurations);
+            applyValue(instance,configValue, false, configurations);
+        };
+    }
+
+
+    /**
+     * Evaluate the initial keys fromMap the configuration and applyChanges it to the field.
+     *
+     * @param target the target instance.
+     * @param configurations Configuration instances that replace configuration served by services. This allows
+     *                       more easily testing and adaption.
+     * @throws ConfigException if evaluation or conversion failed.
+     */
+    public void applyInitialValue(Object target, Configuration... configurations) throws ConfigException {
+        String configValue = InjectionUtils.getConfigValue(this.setterMethod, configurations);
+        applyValue(target, configValue, false, configurations);
+    }
+
+    /**
+     * This method reapplies a changed configuration keys to the field.
+     *
+     * @param target      the target instance, not null.
+     * @param configValue the new keys to be applied, null will trigger the evaluation current the configured default keys.
+     * @param resolve     set to true, if expression resolution should be applied on the keys passed.
+     * @throws org.apache.tamaya.ConfigException if the configuration required could not be resolved or converted.
+     */
+    public void applyValue(Object target, String configValue, boolean resolve, Configuration... configurations) throws ConfigException {
+        Objects.requireNonNull(target);
+        try {
+            if (resolve && configValue != null) {
+                // net step perform exression resolution, if any
+                configValue = Configuration.evaluateValue(configValue, configurations);
+            }
+            // Check for adapter/filter
+            Object value = InjectionUtils.adaptValue(this.setterMethod, this.setterMethod.getParameterTypes()[0], configValue);
+            setterMethod.setAccessible(true);
+            setterMethod.invoke(target, value);
+        } catch (Exception e) {
+            throw new ConfigException("Failed to annotation configured method: " + this.setterMethod.getDeclaringClass()
+                    .getName() + '.' + setterMethod.getName(), e);
+        }
+    }
+
+
+
+    /**
+     * This method checks if the given (qualified) configuration key is referenced fromMap this field.
+     * This is useful to determine, if a key changed in a configuration should trigger any change events
+     * on the related instances.
+     *
+     * @param key the (qualified) configuration key, not null.
+     * @return true, if the key is referenced.
+     */
+    public boolean matchesKey(String key) {
+        DefaultAreas areasAnnot = this.setterMethod.getDeclaringClass().getAnnotation(DefaultAreas.class);
+        Collection<ConfiguredProperty> configuredProperties =
+                Utils.getAnnotations(this.setterMethod, ConfiguredProperty.class, ConfiguredProperties.class);
+        for(ConfiguredProperty prop: configuredProperties) {
+            if (InjectionUtils.evaluateKeys(this.setterMethod, areasAnnot, prop).contains(key)) {
+                return true;
+            }
+        }
+        if (InjectionUtils.evaluateKeys(this.setterMethod, areasAnnot).contains(key)) {
+            return true;
+        }
+        return false;
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/b56817f7/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredType.java b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredType.java
new file mode 100644
index 0000000..879d54a
--- /dev/null
+++ b/modules/injection/src/main/java/org/apache/tamaya/inject/internal/ConfiguredType.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tamaya.core.internal.inject;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+import org.apache.tamaya.core.properties.PropertyChangeSet;
+import org.apache.tamaya.ConfigException;
+import org.apache.tamaya.Configuration;
+import org.apache.tamaya.PropertySource;
+import org.apache.tamaya.annotation.*;
+import org.apache.tamaya.core.internal.Utils;
+
+/**
+ * Structure that contains and manages configuration related things for a configured type registered.
+ * Created by Anatole on 03.10.2014.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class ConfiguredType {
+    /**
+     * A list with all annotated instance variables.
+     */
+    private List<ConfiguredField> configuredFields = new ArrayList<>();
+    /**
+     * A list with all annotated methods (templates).
+     */
+    private List<ConfiguredSetterMethod> configuredSetterMethods = new ArrayList<>();
+    /**
+     * A list with all callback methods listening to config changes.
+     */
+    private List<ConfigChangeCallbackMethod> callbackMethods = new ArrayList<>();
+    /**
+     * The basic type.
+     */
+    private Class type;
+
+    /**
+     * Creates an instance of this class hereby evaluating the config annotations given for later effective
+     * injection (configuration) of instances.
+     *
+     * @param type the instance type.
+     */
+
+    public ConfiguredType(Class type) {
+        this.type = Objects.requireNonNull(type);
+        initFields(type);
+        initMethods(type);
+    }
+
+    private void initFields(Class type) {
+        for (Field f : type.getDeclaredFields()) {
+            if (f.isAnnotationPresent(NoConfig.class)) {
+                continue;
+            }
+            try {
+                ConfiguredField configuredField = new ConfiguredField(f);
+                configuredFields.add(configuredField);
+            } catch (Exception e) {
+                throw new ConfigException("Failed to initialized configured field: " +
+                        f.getDeclaringClass().getName() + '.' + f.getName(), e);
+            }
+        }
+    }
+
+    private void initMethods(Class type) {
+        // TODO revisit this logic here...
+        for (Method m : type.getDeclaredMethods()) {
+            if (m.isAnnotationPresent(NoConfig.class)) {
+                continue;
+            }
+            ObservesConfigChange mAnnot = m.getAnnotation(ObservesConfigChange.class);
+            Collection<ConfiguredProperty> propertiesAnnots = Utils.getAnnotations(m, ConfiguredProperty.class, ConfiguredProperties.class);
+            if (type.isInterface()) {
+                // it is a template
+                if (mAnnot != null) {
+                    if (m.isDefault()) {
+                        addObserverMethod(m);
+                    }
+                } else {
+                    if (m.isDefault()) {
+                        addPropertySetter(m, propertiesAnnots);
+                    }
+                }
+            } else {
+                if (mAnnot != null) {
+                    addObserverMethod(m);
+                } else {
+                    addPropertySetter(m, propertiesAnnots);
+                }
+            }
+        }
+    }
+
+    private boolean addPropertySetter(Method m, Collection<ConfiguredProperty> propertiesAnnots) {
+        if (!propertiesAnnots.isEmpty()) {
+            if (m.getParameterTypes().length == 0) {
+                // getter method
+                Class<?> returnType = m.getReturnType();
+                if (!void.class.equals(returnType)) {
+                    try {
+                        configuredSetterMethods.add(new ConfiguredSetterMethod(m));
+                        return true;
+                    } catch (Exception e) {
+                        throw new ConfigException("Failed to initialized configured setter method: " +
+                                m.getDeclaringClass().getName() + '.' + m.getName(), e);
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+
+
+    private void addObserverMethod(Method m) {
+        if (m.getParameterTypes().length != 1) {
+            return;
+        }
+        if (!m.getParameterTypes()[0].equals(PropertyChangeSet.class)) {
+            return;
+        }
+        if (!void.class.equals(m.getReturnType())) {
+            return;
+        }
+        try {
+            this.callbackMethods.add(new ConfigChangeCallbackMethod(m));
+        } catch (Exception e) {
+            throw new ConfigException("Failed to initialized configured callback method: " +
+                    m.getDeclaringClass().getName() + '.' + m.getName(), e);
+        }
+    }
+
+
+    /**
+     * Method called to configure an instance.
+     *
+     * @param instance       The instance to be configured.
+     * @param configurations Configuration instances that replace configuration served by services. This allows
+     *                       more easily testing and adaption.
+     */
+    public void configure(Object instance, Configuration... configurations) {
+        for (ConfiguredField field : configuredFields) {
+            field.applyInitialValue(instance, configurations);
+        }
+        for (ConfiguredSetterMethod method : configuredSetterMethods) {
+            method.applyInitialValue(instance, configurations);
+            // TODO, if method should be recalled on changes, corresponding callbacks could be registered here
+            WeakConfigListenerManager.of().registerConsumer(instance, method.createConsumer(instance, configurations));
+        }
+        // Register callbacks for this intance (weakly)
+        for (ConfigChangeCallbackMethod callback : callbackMethods) {
+            WeakConfigListenerManager.of().registerConsumer(instance, callback.createConsumer(instance, configurations));
+        }
+    }
+
+
+    private String getName(Object source) {
+        if (source instanceof PropertySource) {
+            PropertySource ps = (PropertySource) source;
+            return ps.getName();
+        }
+        return "N/A";
+    }
+
+
+    public boolean isConfiguredBy(Configuration configuration) {
+        // TODO implement this
+        return true;
+    }
+
+    public static boolean isConfigured(Class type) {
+        if (type.getAnnotation(DefaultAreas.class) != null) {
+            return true;
+        }
+        // if no class level annotation is there we might have field level annotations only
+        for (Field field : type.getDeclaredFields()) {
+            if (field.isAnnotationPresent(ConfiguredProperties.class)) {
+                return true;
+            }
+        }
+        // if no class level annotation is there we might have method level annotations only
+        for (Method method : type.getDeclaredMethods()) {
+            if (method.isAnnotationPresent(ConfiguredProperties.class)) {
+                return true;
+            }
+        }
+        for (Field field : type.getDeclaredFields()) {
+            if (field.isAnnotationPresent(ConfiguredProperty.class)) {
+                return true;
+            }
+        }
+        // if no class level annotation is there we might have method level annotations only
+        for (Method method : type.getDeclaredMethods()) {
+            if (method.isAnnotationPresent(ConfiguredProperty.class)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public Class getType() {
+        return this.type;
+    }
+}