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 2014/12/21 01:36:34 UTC

incubator-tamaya git commit: TAMAYA-34: - Aligned callbacks and method config injections with fallback configuration features. - Added TODOs for possible caching hook points for template methods. - Removed unused listener predicates. - Added central Weak

Repository: incubator-tamaya
Updated Branches:
  refs/heads/master 238c07f16 -> 26e7f2e95


TAMAYA-34:
- Aligned callbacks and method config injections with fallback configuration features.
- Added TODOs for possible caching hook points for template methods.
- Removed unused listener predicates.
- Added central WeakHashmap that maps instances to its listeners weakly.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/commit/26e7f2e9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/tree/26e7f2e9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya/diff/26e7f2e9

Branch: refs/heads/master
Commit: 26e7f2e959dd072c992b9d64d8168a7b325cc04c
Parents: 238c07f
Author: anatole <an...@apache.org>
Authored: Sun Dec 21 01:36:21 2014 +0100
Committer: anatole <an...@apache.org>
Committed: Sun Dec 21 01:36:21 2014 +0100

----------------------------------------------------------------------
 .../java/org/apache/tamaya/Configuration.java   |  10 +-
 .../org/apache/tamaya/ConfigurationManager.java |  10 +-
 .../spi/ConfigurationManagerSingletonSpi.java   |   6 +-
 .../tamaya/TestConfigServiceSingletonSpi.java   |   4 +-
 ...DefaultConfigurationManagerSingletonSpi.java |  31 +----
 .../tamaya/core/internal/config/Store.java      |  98 ----------------
 .../config/WeakConfigListenerManager.java       |  82 -------------
 .../inject/ConfigChangeCallbackMethod.java      |  17 ++-
 .../inject/ConfigTemplateInvocationHandler.java |  11 ++
 .../core/internal/inject/ConfiguredMethod.java  |  53 ++++++---
 .../core/internal/inject/ConfiguredType.java    |  45 +++----
 .../inject/WeakConfigListenerManager.java       | 116 +++++++++++++++++++
 .../tamaya/core/config/MutableConfigTest.java   |   8 +-
 13 files changed, 224 insertions(+), 267 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/Configuration.java b/api/src/main/java/org/apache/tamaya/Configuration.java
index 4248d3c..775078b 100644
--- a/api/src/main/java/org/apache/tamaya/Configuration.java
+++ b/api/src/main/java/org/apache/tamaya/Configuration.java
@@ -340,20 +340,18 @@ public interface Configuration extends PropertySource {
 
     /**
      * Add a ConfigChangeListener to the given PropertySource instance.
-     * @param predicate the event filtering predicate
      * @param l the listener, not null.
      */
-    public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
-        ConfigurationManager.addChangeListener(predicate, l);
+    public static void addChangeListener(Consumer<ConfigChangeSet> l){
+        ConfigurationManager.addChangeListener(l);
     }
 
     /**
      * Removes a ConfigChangeListener from the given PropertySource instance.
-     * @param predicate the event filtering predicate
      * @param l the listener, not null.
      */
-    public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l){
-        ConfigurationManager.removeChangeListener(predicate, l);
+    public static void removeChangeListener(Consumer<ConfigChangeSet> l){
+        ConfigurationManager.removeChangeListener(l);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
index 6c3c009..c753b22 100644
--- a/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
+++ b/api/src/main/java/org/apache/tamaya/ConfigurationManager.java
@@ -112,20 +112,18 @@ final class ConfigurationManager{
 
     /**
      * Add a ConfigChangeSet listener to the given configuration instance.
-     * @param predicate the event filtering predicate, or null, for selecting all changes.
      * @param l the listener, not null.
      */
-    public static void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).addChangeListener(predicate, Objects.requireNonNull(l));
+    public static void addChangeListener(Consumer<ConfigChangeSet> l) {
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).addChangeListener(Objects.requireNonNull(l));
     }
 
     /**
      * Removes a ConfigChangeSet listener from the given configuration instance.
-     * @param predicate the event filtering predicate, or null, for selecting all changes.
      * @param l the listener, not null.
      */
-    public static void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).removeChangeListener(predicate, Objects.requireNonNull(l));
+    public static void removeChangeListener(Consumer<ConfigChangeSet> l) {
+        ServiceContext.getInstance().getSingleton(ConfigurationManagerSingletonSpi.class).removeChangeListener(Objects.requireNonNull(l));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
index 2bbc180..6be15a8 100644
--- a/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
+++ b/api/src/main/java/org/apache/tamaya/spi/ConfigurationManagerSingletonSpi.java
@@ -95,17 +95,15 @@ public interface ConfigurationManagerSingletonSpi{
 
     /**
      * Add a ConfigChangeSet listener to the given configuration instance.
-     * @param predicate the event filtering predicate, or null, for selecting all changes.
      * @@param l the listener, not null.
      */
-    void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+    void addChangeListener(Consumer<ConfigChangeSet> l);
 
     /**
      * Removes a ConfigChangeSet listener from the given configuration instance.
-     * @param predicate the event filtering predicate, or null, for selecting all changes.
      * @param l the listener, not null.
      */
-    void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l);
+    void removeChangeListener(Consumer<ConfigChangeSet> l);
 
     /**
      * Method to publish changes on a {@link org.apache.tamaya.Configuration} to all interested parties.

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
----------------------------------------------------------------------
diff --git a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
index 2d0694f..89f8078 100644
--- a/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
+++ b/api/src/test/java/org/apache/tamaya/TestConfigServiceSingletonSpi.java
@@ -89,12 +89,12 @@ public class TestConfigServiceSingletonSpi implements ConfigurationManagerSingle
     }
 
     @Override
-    public void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+    public void addChangeListener(Consumer<ConfigChangeSet> l) {
         // ignore
     }
 
     @Override
-    public void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
+    public void removeChangeListener(Consumer<ConfigChangeSet> l) {
         // ignore
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
index cb096e8..2b0a471 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/config/DefaultConfigurationManagerSingletonSpi.java
@@ -35,6 +35,7 @@ import org.apache.tamaya.PropertySource;
 import org.apache.tamaya.core.internal.el.DefaultExpressionEvaluator;
 import org.apache.tamaya.core.internal.inject.ConfigTemplateInvocationHandler;
 import org.apache.tamaya.core.internal.inject.ConfigurationInjector;
+import org.apache.tamaya.core.internal.inject.WeakConfigListenerManager;
 import org.apache.tamaya.core.spi.ConfigurationProviderSpi;
 import org.apache.tamaya.core.spi.ExpressionEvaluator;
 import org.apache.tamaya.spi.ConfigurationManagerSingletonSpi;
@@ -51,8 +52,6 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
 
     private Map<String, ConfigurationProviderSpi> configProviders = new ConcurrentHashMap<>();
 
-    private Map<Consumer<ConfigChangeSet>, List<Predicate<PropertySource>>> listenerMap = new ConcurrentHashMap<>();
-
     private ExpressionEvaluator expressionEvaluator = loadEvaluator();
 
     private ExpressionEvaluator loadEvaluator() {
@@ -94,36 +93,18 @@ public class DefaultConfigurationManagerSingletonSpi implements ConfigurationMan
     }
 
     @Override
-    public void addChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        List<Predicate<PropertySource>> predicates = listenerMap.computeIfAbsent(l,
-                cs -> Collections.synchronizedList(new ArrayList<>()));
-        if (predicate == null) {
-            predicates.add(p -> true); // select all events!
-        } else {
-            predicates.add(predicate);
-        }
+    public void addChangeListener(Consumer<ConfigChangeSet> l) {
+        WeakConfigListenerManager.of().registerConsumer(l,l);
     }
 
     @Override
-    public void removeChangeListener(Predicate<PropertySource> predicate, Consumer<ConfigChangeSet> l) {
-        List<Predicate<PropertySource>> predicates = listenerMap.get(l);
-        if (predicate == null) {
-            listenerMap.remove(l); // select all events!
-        } else {
-            predicates.add(predicate);
-        }
+    public void removeChangeListener(Consumer<ConfigChangeSet> l) {
+        WeakConfigListenerManager.of().unregisterConsumer(l);
     }
 
     @Override
     public void publishChange(ConfigChangeSet configChangeSet) {
-        listenerMap.entrySet().forEach(
-                (en) -> {
-                    if (en.getValue().stream()
-                            .filter(v -> v.test(configChangeSet.getPropertySource())).findAny().isPresent()) {
-                        en.getKey().accept(configChangeSet);
-                    }
-                }
-        );
+        WeakConfigListenerManager.of().publishChangeEvent(configChangeSet);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java b/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
deleted file mode 100644
index 815e0f3..0000000
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/Store.java
+++ /dev/null
@@ -1,98 +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 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.config;
-
-import java.lang.ref.WeakReference;
-import java.util.*;
-
-/**
- * This store encapsulates an list current WeakReferences to items.
- * It cleans up the list fromMap null references, when an item is removed, or an Iterator is created.
- * Created by Anatole on 10.04.2014.
- */
-public class Store<T>implements Iterable<T> {
-
-    private List<WeakReference<T>> weakItems = new ArrayList<>();
-
-    private List<T> items = new ArrayList<>();
-
-    private final Object LOCK = new Object();
-
-    public void add(T item){
-        Objects.requireNonNull(item);
-        this.items.add(item);
-    }
-
-    public void addWeak(T item){
-        Objects.requireNonNull(item);
-        this.weakItems.add(new WeakReference<>(item));
-    }
-
-    public void remove(T item){
-        Objects.requireNonNull(item);
-        synchronized(LOCK){
-            for(Iterator<WeakReference<T>> iter = weakItems.iterator(); iter.hasNext();iter.next()){
-                WeakReference<T> wr = iter.next();
-                T t = wr.get();
-                if(t==null || t.equals(item)){
-                    iter.remove();
-                }
-            }
-            for(Iterator<T> iter = items.iterator(); iter.hasNext();iter.next()){
-                T t = iter.next();
-                if(t==null || t.equals(item)){
-                    iter.remove();
-                }
-            }
-        }
-    }
-
-    public List<T> toList(){
-        List<T> newList = new ArrayList<>();
-        synchronized(LOCK){
-            Iterator<T> iter = items.iterator();
-            while(iter.hasNext()){
-                T t = iter.next();
-                newList.add(t);
-            }
-            for (WeakReference<T> wr : weakItems) {
-                T t = wr.get();
-                if (t == null) {
-                    iter.remove();
-                } else {
-                    newList.add(t);
-                }
-            }
-        }
-        return newList;
-    }
-
-    @Override
-    public Iterator<T> iterator(){
-        return toList().iterator();
-    }
-
-    @Override
-    public String toString(){
-        return "Store{" +
-                "items=" + items +
-                ", weakItems=" + weakItems +
-                '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java b/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
deleted file mode 100644
index 7cc6a15..0000000
--- a/core/src/main/java/org/apache/tamaya/core/internal/config/WeakConfigListenerManager.java
+++ /dev/null
@@ -1,82 +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 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.config;
-
-
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Simple listener container that only holds weak references on the listeners.
- */
-public class WeakConfigListenerManager{
-
-    private static final Logger LOG = Logger.getLogger(WeakConfigListenerManager.class.getName());
-    private Map<String,Store<PropertyChangeListener>> changeListeners = new ConcurrentHashMap<>();
-
-
-    private void publishPropertyChangeEventToGlobalListeners(PropertyChangeEvent evt){
-        Store<PropertyChangeListener> items = changeListeners.get("_globalConfigChangeListeners");
-        if(items != null){
-            synchronized(items){
-                for(PropertyChangeListener l : items){
-                    try{
-                        l.propertyChange(evt);
-                    }
-                    catch(Exception e){
-                        LOG.log(Level.SEVERE, e, () -> "Error thrown by PropertyChangeListener: " + l);
-                    }
-                }
-
-            }
-        }
-    }
-
-
-    public void publishPropertyChangeEvent(PropertyChangeEvent evt, String configId){
-        Store<PropertyChangeListener> items = changeListeners.get(configId);
-        if(items != null){
-            synchronized(items){
-                for(PropertyChangeListener l : items){
-                    try{
-                        l.propertyChange(evt);
-                    }
-                    catch(Exception e){
-                        LOG.log(Level.SEVERE, e, () -> "Error thrown by ConfigChangeListener: " + l);
-                    }
-                }
-
-            }
-        }
-        publishPropertyChangeEventToGlobalListeners(evt);
-    }
-
-
-    @Override
-    public String toString(){
-        return "WeakConfigListenerManager{" +
-                "changeListeners=" + changeListeners +
-                '}';
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
index 8bf951a..882d68b 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigChangeCallbackMethod.java
@@ -18,10 +18,14 @@
  */
 package org.apache.tamaya.core.internal.inject;
 
+import org.apache.tamaya.ConfigChangeSet;
+import org.apache.tamaya.Configuration;
+
 import java.beans.PropertyChangeEvent;
 import java.lang.reflect.Method;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.function.Consumer;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -43,7 +47,18 @@ public final class ConfigChangeCallbackMethod {
                         m.getParameterTypes()[0].equals(PropertyChangeEvent.class)).get();
     }
 
-    public void call(Object instance, PropertyChangeEvent configChangeEvent) {
+    public Consumer<ConfigChangeSet> createConsumer(Object instance, Configuration... configurations){
+        return event -> {
+            for(Configuration cfg:configurations){
+                if(event.getPropertySource().getMetaInfo().getName().equals(cfg.getMetaInfo().getName())){
+                    return;
+                }
+            }
+            call(instance, event);
+        };
+    }
+
+    public void call(Object instance, ConfigChangeSet configChangeEvent) {
         try {
             callbackMethod.setAccessible(true);
             callbackMethod.invoke(instance, configChangeEvent);

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
index 70070c5..ff2c309 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfigTemplateInvocationHandler.java
@@ -30,6 +30,17 @@ 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.
      */

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
index 8c1e0af..c3dda19 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredMethod.java
@@ -22,20 +22,20 @@ import java.lang.reflect.Method;
 import java.util.Collection;
 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, conversiong any applying the
+ * 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.
- * Created by Anatole on 01.10.2014.
  */
 public class ConfiguredMethod {
 
-
     /**
      * The configured field instance.
      */
@@ -51,7 +51,43 @@ public class ConfiguredMethod {
     }
 
 
+    /**
+     * 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.annotatedMethod, 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.annotatedMethod, this.annotatedMethod.getParameterTypes()[0], configValue);
+            annotatedMethod.setAccessible(true);
+            annotatedMethod.invoke(target, value);
+        } catch (Exception e) {
+            throw new ConfigException("Failed to annotation configured method: " + this.annotatedMethod.getDeclaringClass()
+                    .getName() + '.' + annotatedMethod.getName(), e);
+        }
+    }
 
 
 
@@ -76,14 +112,5 @@ public class ConfiguredMethod {
     }
 
 
-//    /**
-//     * This method reapplies a changed configuration keys to the field.
-//     *
-//     * @throws org.apache.tamaya.ConfigException if the configuration required could not be resolved or converted.
-//     */
-//    public Object getValue(Object[] args, Configuration... configurations) throws ConfigException {
-//        // TODO do something with additional args?
-//        return InjectionUtils.adaptValue(this.annotatedMethod, this.annotatedMethod.getReturnType(), configValue);
-//    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
index eef9923..491041d 100644
--- a/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/ConfiguredType.java
@@ -21,11 +21,7 @@ package org.apache.tamaya.core.internal.inject;
 import java.beans.PropertyChangeEvent;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 import org.apache.tamaya.ConfigException;
 import org.apache.tamaya.Configuration;
@@ -34,6 +30,7 @@ import org.apache.tamaya.annotation.ConfiguredProperties;
 import org.apache.tamaya.annotation.ConfiguredProperty;
 import org.apache.tamaya.annotation.DefaultAreas;
 import org.apache.tamaya.annotation.ObservesConfigChange;
+import org.apache.tamaya.core.internal.Utils;
 
 /**
  * Structure that contains and manages configuration related things for a configured type registered.
@@ -44,7 +41,7 @@ public class ConfiguredType {
     /** A list with all annotated instance variables. */
     private List<ConfiguredField> configuredFields = new ArrayList<>();
     /** A list with all annotated methods (templates). */
-    private Map<Method, ConfiguredMethod> configuredMethods = new HashMap<>();
+    private List<ConfiguredMethod> configuredMethods = new ArrayList<>();
     /** A list with all callback methods listening to config changes. */
     private List<ConfigChangeCallbackMethod> callbackMethods = new ArrayList<>();
     /** The basic type. */
@@ -82,26 +79,15 @@ public class ConfiguredType {
                             m.getDeclaringClass().getName() + '.' + m.getName(), e);
                 }
             } else {
-                ConfiguredProperties propertiesAnnot = m.getAnnotation(ConfiguredProperties.class);
-                if (propertiesAnnot != null) {
+                Collection<ConfiguredProperty> propertiesAnnots = Utils.getAnnotations(m, ConfiguredProperty.class, ConfiguredProperties.class);
+                if (!propertiesAnnots.isEmpty()) {
                     try {
                         ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
-                        configuredMethods.put(m, configuredMethod);
+                        configuredMethods.add(configuredMethod);
                     } catch (Exception e) {
                         throw new ConfigException("Failed to initialized configured method: " +
                                 m.getDeclaringClass().getName() + '.' + m.getName(), e);
                     }
-                } else {
-                    ConfiguredProperty propertyAnnot = m.getAnnotation(ConfiguredProperty.class);
-                    if (propertyAnnot != null) {
-                        try {
-                            ConfiguredMethod configuredMethod = new ConfiguredMethod(m);
-                            configuredMethods.put(m, configuredMethod);
-                        } catch (Exception e) {
-                            throw new ConfigException("Failed to initialized configured method: " +
-                                    m.getDeclaringClass().getName() + '.' + m.getName(), e);
-                        }
-                    }
                 }
             }
         }
@@ -142,18 +128,20 @@ public class ConfiguredType {
      */
     public void configure(Object instance, Configuration... configurations) {
         for (ConfiguredField field : configuredFields) {
-            field.applyInitialValue(instance);
+            field.applyInitialValue(instance, configurations);
+            // TODO, if reinjection on changes should be done, corresponding callbacks could be registered here
         }
-    }
-
-    public void triggerConfigUpdate(PropertyChangeEvent evt, Object instance) {
-        // TODO do check for right config ;)
-        configuredFields.stream().filter(field -> field.matchesKey(getName(evt.getSource()), evt.getPropertyName())).forEach(field -> field.applyValue(instance, (String) evt.getNewValue(), false));
-        for (ConfigChangeCallbackMethod callBack : this.callbackMethods) {
-            callBack.call(instance, evt);
+        for (ConfiguredMethod method : configuredMethods) {
+            method.applyInitialValue(instance, configurations);
+            // TODO, if method should be recalled on changes, corresponding callbacks could be registered here
+        }
+        // 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;
@@ -162,6 +150,7 @@ public class ConfiguredType {
         return "N/A";
     }
 
+
     public boolean isConfiguredBy(Configuration configuration) {
         // TODO implement this
         return true;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java b/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
new file mode 100644
index 0000000..6f19bbe
--- /dev/null
+++ b/core/src/main/java/org/apache/tamaya/core/internal/inject/WeakConfigListenerManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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.ConfigChangeSet;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.StampedLock;
+import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Simple listener container that only holds weak references on the listeners.
+ */
+public final class WeakConfigListenerManager{
+
+    private static final WeakConfigListenerManager INSTANCE = new WeakConfigListenerManager();
+
+    private static final Logger LOG = Logger.getLogger(WeakConfigListenerManager.class.getName());
+    private StampedLock lock = new StampedLock();
+    private Map<Object,Consumer<ConfigChangeSet>> listenerReferences = new WeakHashMap<>();
+
+    /** Private singleton constructor. */
+    private WeakConfigListenerManager(){}
+
+    public static WeakConfigListenerManager of(){
+        return INSTANCE;
+    }
+
+    /**
+     * Registers the given consumer for the instance. If a consumer already exists for this instance the given
+     * consumer is appended.
+     * @param instance the instance, not null.
+     * @param listener the consumer.
+     */
+    public void registerConsumer(Object instance, Consumer<ConfigChangeSet> listener){
+        Lock writeLock = lock.asWriteLock();
+        try {
+            writeLock.lock();
+            Consumer<ConfigChangeSet> l = listenerReferences.get(instance);
+            if (l == null) {
+                listenerReferences.put(instance, listener);
+            } else {
+                listenerReferences.put(instance, l.andThen(listener));
+            }
+        }
+        finally{
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Unregisters all consumers for the given instance.
+     * @param instance the instance, not null.
+     */
+    public void unregisterConsumer(Object instance) {
+        Lock writeLock = lock.asWriteLock();
+        try {
+            writeLock.lock();
+            listenerReferences.remove(instance);
+        }
+        finally{
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Publishes a change event to all consumers registered.
+     * @param change the change event, not null.
+     */
+    public void publishChangeEvent(ConfigChangeSet change){
+        Lock readLock = lock.asReadLock();
+        try{
+            readLock.lock();
+            listenerReferences.values().parallelStream().forEach(l -> {
+                try{
+                    l.accept(change);
+                }
+                catch(Exception e){
+                    LOG.log(Level.SEVERE, "ConfigChangeListener failed: " + l.getClass().getName(), e);
+                }
+            });
+        }
+        finally{
+            readLock.unlock();
+        }
+    }
+
+
+    @Override
+    public String toString(){
+        return "WeakConfigListenerManager{" +
+                "listenerReferences=" + listenerReferences +
+                '}';
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-tamaya/blob/26e7f2e9/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java b/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
index 0f81a10..215da35 100644
--- a/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
+++ b/core/src/test/java/org/apache/tamaya/core/config/MutableConfigTest.java
@@ -35,12 +35,16 @@ import static org.junit.Assert.assertFalse;
 public class MutableConfigTest {
 
     @Test
-    public void accessMutableConfig(){
+    public void accessMutableConfig() {
         Configuration config = Configuration.current("mutableTestConfig");
         ConfigChangeSet changeSet = ConfigChangeSetBuilder.of(config).put("testCase", "accessMutableConfig")
                 .put("execTime", System.currentTimeMillis()).put("execution", "once").build();
         List<PropertyChangeEvent> changes = new ArrayList<>();
-        Configuration.addChangeListener(cfg -> cfg == config, change -> changes.addAll(change.getEvents()));
+        Configuration.addChangeListener(change -> {
+            if (change.getPropertySource() == config) {
+                changes.addAll(change.getEvents());
+            }
+        });
         config.applyChanges(changeSet);
         assertFalse(changes.isEmpty());
         System.out.println(changes);