You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/08/22 11:45:24 UTC

[camel] branch CAMEL-13870 updated (233d9e4 -> 56b4e8d)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch CAMEL-13870
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 233d9e4  CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.
     new 3b87d78  CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.
     new 56b4e8d  CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/camel/spi/BeanIntrospection.java    | 40 +++++++---
 .../impl/engine/DefaultBeanIntrospection.java      | 79 ++++++++++++++------
 .../camel/main/DefaultConfigurationConfigurer.java |  5 ++
 .../camel/main/DefaultConfigurationProperties.java | 27 +++++++
 .../camel-main-configuration-metadata.json         | 12 +++
 .../mbean/ManagedBeanIntrospectionMBean.java       |  6 ++
 .../management/mbean/ManagedBeanIntrospection.java | 10 +++
 .../DefaultComponentVerifierExtension.java         |  4 +-
 .../org/apache/camel/support/DefaultComponent.java |  3 +-
 .../org/apache/camel/support/DefaultEndpoint.java  |  3 +-
 .../apache/camel/support/IntrospectionSupport.java | 15 ++++
 .../camel/support/ScheduledPollEndpoint.java       |  3 +-
 .../org/apache/camel/util/PropertiesHelper.java    | 86 ++++++++++++++++++++++
 .../src/main/resources/application.properties      |  4 +
 14 files changed, 261 insertions(+), 36 deletions(-)
 create mode 100644 core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java


[camel] 02/02: CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-13870
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 56b4e8dc409406bcfea7069f0413143ad34d4b42
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Aug 22 13:45:10 2019 +0200

    CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.
---
 .../org/apache/camel/spi/BeanIntrospection.java    | 13 +++++-
 .../impl/engine/DefaultBeanIntrospection.java      | 54 +++++++++++++++++++---
 .../camel/main/DefaultConfigurationConfigurer.java |  5 ++
 .../camel/main/DefaultConfigurationProperties.java | 27 +++++++++++
 .../camel-main-configuration-metadata.json         | 12 +++++
 .../apache/camel/support/IntrospectionSupport.java |  4 ++
 .../org/apache/camel/util/PropertiesHelper.java    | 17 +++++++
 .../src/main/resources/application.properties      |  4 ++
 8 files changed, 128 insertions(+), 8 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java b/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
index fd63878..a116ab7 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.StaticService;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.meta.Experimental;
@@ -81,6 +82,16 @@ public interface BeanIntrospection extends StaticService {
      */
     void setExtendedStatistics(boolean extendedStatistics);
 
+    /**
+     * Logging level used for logging introspection usage. Is using DEBUG level as default.
+     */
+    LoggingLevel getLoggingLevel();
+
+    /**
+     * Logging level used for logging introspection usage. Is using DEBUG level as default.
+     */
+    void setLoggingLevel(LoggingLevel loggingLevel);
+
     // Introspection
     // ----------------------------------------------------
 
@@ -139,8 +150,6 @@ public interface BeanIntrospection extends StaticService {
      */
     ClassInfo cacheClass(Class<?> clazz);
 
-    boolean hasProperties(Map<String, Object> properties, String optionPrefix);
-
     Object getProperty(Object target, String propertyName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException;
 
     Object getOrElseProperty(Object target, String propertyName, Object defaultValue);
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
index 0e08eaa..20936dd 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
@@ -23,8 +23,10 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.support.IntrospectionSupport;
 import org.apache.camel.support.service.ServiceSupport;
 import org.slf4j.Logger;
@@ -37,6 +39,8 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
 
     private final AtomicLong invoked = new AtomicLong();
     private volatile boolean extendedStatistics;
+    private LoggingLevel loggingLevel = LoggingLevel.DEBUG;
+    private CamelLogger logger = new CamelLogger(LOG, loggingLevel);
 
     @Override
     public long getInvokedCounter() {
@@ -56,8 +60,25 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
         this.extendedStatistics = extendedStatistics;
     }
 
+    public LoggingLevel getLoggingLevel() {
+        return loggingLevel;
+    }
+
+    public void setLoggingLevel(LoggingLevel loggingLevel) {
+        this.loggingLevel = loggingLevel;
+        // recreate logger as level is changed
+        this.logger = new CamelLogger(LOG, loggingLevel);
+    }
+
+    private void log(String method, Object bean) {
+        if (logger.shouldLog()) {
+            logger.log("Invoked: " + invoked.get() + " times (overall) [Method: " + method + ", Argument: " + bean + "]");
+        }
+    }
+
     @Override
     public ClassInfo cacheClass(Class<?> clazz) {
+        log("cacheClass", clazz);
         invoked.incrementAndGet();
         return IntrospectionSupport.cacheClass(clazz);
     }
@@ -95,59 +116,63 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Override
     public boolean getProperties(Object target, Map<String, Object> properties, String optionPrefix) {
         invoked.incrementAndGet();
+        log("getProperties", target);
         return IntrospectionSupport.getProperties(target, properties, optionPrefix);
     }
 
     @Override
     public boolean getProperties(Object target, Map<String, Object> properties, String optionPrefix, boolean includeNull) {
         invoked.incrementAndGet();
+        log("getProperties", target);
         return IntrospectionSupport.getProperties(target, properties, optionPrefix, includeNull);
     }
 
     @Override
-    public boolean hasProperties(Map<String, Object> properties, String optionPrefix) {
-        return IntrospectionSupport.hasProperties(properties, optionPrefix);
-    }
-
-    @Override
     public Object getProperty(Object target, String propertyName) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
         invoked.incrementAndGet();
+        log("getProperty", target);
         return IntrospectionSupport.getProperty(target, propertyName);
     }
 
     @Override
     public Object getOrElseProperty(Object target, String propertyName, Object defaultValue) {
         invoked.incrementAndGet();
+        log("getOrElseProperty", target);
         return IntrospectionSupport.getOrElseProperty(target, propertyName, defaultValue);
     }
 
     @Override
     public Object getOrElseProperty(Object target, String propertyName, Object defaultValue, boolean ignoreCase) {
         invoked.incrementAndGet();
+        log("getOrElseProperty", target);
         return IntrospectionSupport.getOrElseProperty(target, propertyName, defaultValue, ignoreCase);
     }
 
     @Override
     public Method getPropertyGetter(Class<?> type, String propertyName) throws NoSuchMethodException {
         invoked.incrementAndGet();
+        log("getPropertyGetter", type);
         return IntrospectionSupport.getPropertyGetter(type, propertyName);
     }
 
     @Override
     public Method getPropertyGetter(Class<?> type, String propertyName, boolean ignoreCase) throws NoSuchMethodException {
         invoked.incrementAndGet();
+        log("getPropertyGetter", type);
         return IntrospectionSupport.getPropertyGetter(type, propertyName, ignoreCase);
     }
 
     @Override
     public Method getPropertySetter(Class<?> type, String propertyName) throws NoSuchMethodException {
         invoked.incrementAndGet();
+        log("getPropertySetter", type);
         return IntrospectionSupport.getPropertySetter(type, propertyName);
     }
 
     @Override
     public boolean isPropertyIsGetter(Class<?> type, String propertyName) {
         invoked.incrementAndGet();
+        log("isPropertyIsGetter", type);
         return IntrospectionSupport.isPropertyIsGetter(type, propertyName);
     }
 
@@ -155,6 +180,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperties(Object target, Map<String, Object> properties, String optionPrefix, boolean allowBuilderPattern) throws Exception {
         invoked.incrementAndGet();
+        log("setProperties", target);
         return IntrospectionSupport.setProperties(target, properties, optionPrefix, allowBuilderPattern);
     }
 
@@ -162,6 +188,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperties(Object target, Map<String, Object> properties, String optionPrefix) throws Exception {
         invoked.incrementAndGet();
+        log("setProperties", target);
         return IntrospectionSupport.setProperties(target, properties, optionPrefix);
     }
 
@@ -169,6 +196,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperties(CamelContext context, TypeConverter typeConverter, Object target, Map<String, Object> properties) throws Exception {
         invoked.incrementAndGet();
+        log("setProperties", target);
         return IntrospectionSupport.setProperties(context, typeConverter, target, properties);
     }
 
@@ -176,6 +204,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperties(TypeConverter typeConverter, Object target, Map<String, Object> properties) throws Exception {
         invoked.incrementAndGet();
+        log("setProperties", target);
         return IntrospectionSupport.setProperties(typeConverter, target, properties);
     }
 
@@ -183,36 +212,42 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperties(Object target, Map<String, Object> properties) throws Exception {
         invoked.incrementAndGet();
+        log("setProperties", target);
         return IntrospectionSupport.setProperties(target, properties);
     }
 
     @Override
     public boolean setProperty(CamelContext context, TypeConverter typeConverter, Object target, String name, Object value, String refName, boolean allowBuilderPattern) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(context, typeConverter, target, name, value, refName, allowBuilderPattern);
     }
 
     @Override
     public boolean setProperty(CamelContext context, TypeConverter typeConverter, Object target, String name, Object value, String refName, boolean allowBuilderPattern, boolean allowPrivateSetter, boolean ignoreCase) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(context, typeConverter, target, name, value, refName, allowBuilderPattern, allowPrivateSetter, ignoreCase);
     }
 
     @Override
     public boolean setProperty(CamelContext context, Object target, String name, Object value) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(context, target, name, value);
     }
 
     @Override
     public boolean setProperty(CamelContext context, TypeConverter typeConverter, Object target, String name, Object value) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(context, typeConverter, target, name, value);
     }
 
     @Override
     public boolean setProperty(TypeConverter typeConverter, Object target, String name, Object value) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(typeConverter, target, name, value);
     }
 
@@ -220,6 +255,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperty(Object target, String name, Object value, boolean allowBuilderPattern) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(target, name, value, allowBuilderPattern);
     }
 
@@ -227,12 +263,14 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Deprecated
     public boolean setProperty(Object target, String name, Object value) throws Exception {
         invoked.incrementAndGet();
+        log("setProperty", target);
         return IntrospectionSupport.setProperty(target, name, value);
     }
 
     @Override
     public Set<Method> findSetterMethods(Class<?> clazz, String name, boolean allowBuilderPattern, boolean allowPrivateSetter, boolean ignoreCase) {
         invoked.incrementAndGet();
+        log("findSetterMethods", clazz);
         return IntrospectionSupport.findSetterMethods(clazz, name, allowBuilderPattern, allowPrivateSetter, ignoreCase);
     }
 
@@ -244,6 +282,10 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     @Override
     protected void doStop() throws Exception {
         IntrospectionSupport.stop();
-        LOG.debug("BeanIntrospection invoked: {} times", getInvokedCounter());
+        if (extendedStatistics) {
+            LOG.info("BeanIntrospection invoked: {} times", getInvokedCounter());
+        } else {
+            LOG.debug("BeanIntrospection invoked: {} times", getInvokedCounter());
+        }
     }
 }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 6dbaf1e..88de495 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -85,6 +85,11 @@ public final class DefaultConfigurationConfigurer {
      * @param config       the configuration
      */
     public static void configure(CamelContext camelContext, DefaultConfigurationProperties config) throws Exception {
+        camelContext.getExtension(ExtendedCamelContext.class).getBeanIntrospection().setExtendedStatistics(config.isBeanIntrospectionExtendedStatistics());
+        if (config.getBeanIntrospectionLoggingLevel() != null) {
+            camelContext.getExtension(ExtendedCamelContext.class).getBeanIntrospection().setLoggingLevel(config.getBeanIntrospectionLoggingLevel());
+        }
+
         if (!config.isJmxEnabled()) {
             camelContext.disableJMX();
         }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 25c0548..e2d451a 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.main;
 
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.ManagementStatisticsLevel;
 import org.apache.camel.support.PatternHelper;
 
@@ -68,6 +69,8 @@ public abstract class DefaultConfigurationProperties<T> {
     private String threadNamePattern;
     private String routeFilterIncludePattern;
     private String routeFilterExcludePattern;
+    private boolean beanIntrospectionExtendedStatistics;
+    private LoggingLevel beanIntrospectionLoggingLevel;
 
     // getter and setters
     // --------------------------------------------------------------
@@ -677,6 +680,30 @@ public abstract class DefaultConfigurationProperties<T> {
         this.routeFilterExcludePattern = exclude;
     }
 
+    public boolean isBeanIntrospectionExtendedStatistics() {
+        return beanIntrospectionExtendedStatistics;
+    }
+
+    /**
+     * Sets whether bean introspection uses extended statistics.
+     * The default is false.
+     */
+    public void setBeanIntrospectionExtendedStatistics(boolean beanIntrospectionExtendedStatistics) {
+        this.beanIntrospectionExtendedStatistics = beanIntrospectionExtendedStatistics;
+    }
+
+    public LoggingLevel getBeanIntrospectionLoggingLevel() {
+        return beanIntrospectionLoggingLevel;
+    }
+
+    /**
+     * Sets the logging level used by bean introspection, logging activity of its usage.
+     * The default is DEBUG.
+     */
+    public void setBeanIntrospectionLoggingLevel(LoggingLevel beanIntrospectionLoggingLevel) {
+        this.beanIntrospectionLoggingLevel = beanIntrospectionLoggingLevel;
+    }
+
     // fluent builders
     // --------------------------------------------------------------
 
diff --git a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
index 6170560..6758d86 100644
--- a/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/main/resources/META-INF/camel-main-configuration-metadata.json
@@ -85,6 +85,18 @@
 			"description":"Sets whether backlog tracing is enabled or not. Default is false."
 		},
 		{
+			"name":"camel.main.bean-introspection-extended-statistics",
+			"type":"boolean",
+			"sourceType":"org.apache.camel.main.DefaultConfigurationProperties",
+			"description":"Sets whether bean introspection uses extended statistics. The default is false."
+		},
+		{
+			"name":"camel.main.bean-introspection-logging-level",
+			"type":"org.apache.camel.LoggingLevel",
+			"sourceType":"org.apache.camel.main.DefaultConfigurationProperties",
+			"description":"Sets the logging level used by bean introspection, logging activity of its usage. The default is DEBUG."
+		},
+		{
 			"name":"camel.main.consumer-template-cache-size",
 			"type":"int",
 			"sourceType":"org.apache.camel.main.DefaultConfigurationProperties",
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
index f214af2..9ae6457 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
@@ -333,6 +333,10 @@ public final class IntrospectionSupport {
         return answer;
     }
 
+    /**
+     * @deprecated use {@link org.apache.camel.util.PropertiesHelper}
+     */
+    @Deprecated
     public static boolean hasProperties(Map<String, Object> properties, String optionPrefix) {
         ObjectHelper.notNull(properties, "properties");
 
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java
index baa25ee..aa0239e 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java
@@ -66,4 +66,21 @@ public final class PropertiesHelper {
         return rc;
     }
 
+    public static boolean hasProperties(Map<String, Object> properties, String optionPrefix) {
+        ObjectHelper.notNull(properties, "properties");
+
+        if (ObjectHelper.isNotEmpty(optionPrefix)) {
+            for (Object o : properties.keySet()) {
+                String name = (String) o;
+                if (name.startsWith(optionPrefix)) {
+                    return true;
+                }
+            }
+            // no parameters with this prefix
+            return false;
+        } else {
+            return !properties.isEmpty();
+        }
+    }
+    
 }
diff --git a/examples/camel-example-main/src/main/resources/application.properties b/examples/camel-example-main/src/main/resources/application.properties
index b0cb4a5..242773d 100644
--- a/examples/camel-example-main/src/main/resources/application.properties
+++ b/examples/camel-example-main/src/main/resources/application.properties
@@ -20,6 +20,10 @@
 camel.main.name = MyCoolCamel
 camel.main.jmx-enabled = false
 
+# extended runtime statistics about bean introspection usage (java reflection)
+# camel.main.bean-introspection-extended-statistics=true
+# camel.main.bean-introspection-logging-level=INFO
+
 # enable tracing
 # camel.main.tracing = true
 # configure tracing what to include from the exchange


[camel] 01/02: CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-13870
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3b87d7806810ba4d3291cef452af6acd4ebc1b44
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Aug 22 13:05:30 2019 +0200

    CAMEL-13870: Fast property configuration of Camel endpoints. Work in progress.
---
 .../org/apache/camel/spi/BeanIntrospection.java    | 27 ++++++---
 .../impl/engine/DefaultBeanIntrospection.java      | 25 +++-----
 .../mbean/ManagedBeanIntrospectionMBean.java       |  6 ++
 .../management/mbean/ManagedBeanIntrospection.java | 10 ++++
 .../DefaultComponentVerifierExtension.java         |  4 +-
 .../org/apache/camel/support/DefaultComponent.java |  3 +-
 .../org/apache/camel/support/DefaultEndpoint.java  |  3 +-
 .../apache/camel/support/IntrospectionSupport.java | 11 ++++
 .../camel/support/ScheduledPollEndpoint.java       |  3 +-
 .../org/apache/camel/util/PropertiesHelper.java    | 69 ++++++++++++++++++++++
 10 files changed, 133 insertions(+), 28 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java b/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
index 176bff4..fd63878 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BeanIntrospection.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import org.apache.camel.CamelContext;
 import org.apache.camel.StaticService;
 import org.apache.camel.TypeConverter;
+import org.apache.camel.meta.Experimental;
 
 // TODO: Keep only public used methods so we can remove the tech debt
 
@@ -32,7 +33,10 @@ import org.apache.camel.TypeConverter;
  * or updating one or more properties etc.
  *
  * End users should favour using org.apache.camel.support.PropertyBindingSupport instead.
+ * <p/>
+ * Notice this API is not final yet
  */
+@Experimental
 public interface BeanIntrospection extends StaticService {
 
     /**
@@ -54,6 +58,9 @@ public interface BeanIntrospection extends StaticService {
         public Boolean hasGetterAndSetter;
     }
 
+    // Statistics
+    // ----------------------------------------------------
+
     /**
      * Number of times bean introspection has been invoked
      */
@@ -64,6 +71,19 @@ public interface BeanIntrospection extends StaticService {
      */
     void resetCounters();
 
+    /**
+     * Whether to gather extended statistics for introspection usage.
+     */
+    boolean isExtendedStatistics();
+
+    /**
+     * Whether to gather extended statistics for introspection usage.
+     */
+    void setExtendedStatistics(boolean extendedStatistics);
+
+    // Introspection
+    // ----------------------------------------------------
+
     boolean isGetter(Method method);
 
     String getGetterShorthandName(Method method);
@@ -147,13 +167,6 @@ public interface BeanIntrospection extends StaticService {
     @Deprecated
     boolean setProperties(Object target, Map<String, Object> properties, String optionPrefix) throws Exception;
 
-    Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix);
-
-    Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix, boolean remove);
-
-    @Deprecated
-    Map<String, String> extractStringProperties(Map<String, Object> properties);
-
     /**
      * @deprecated use org.apache.camel.support.PropertyBindingSupport
      */
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
index 4963104..0e08eaa 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
@@ -36,6 +36,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     private static final Logger LOG = LoggerFactory.getLogger(DefaultBeanIntrospection.class);
 
     private final AtomicLong invoked = new AtomicLong();
+    private volatile boolean extendedStatistics;
 
     @Override
     public long getInvokedCounter() {
@@ -47,6 +48,14 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
         invoked.set(0);
     }
 
+    public boolean isExtendedStatistics() {
+        return extendedStatistics;
+    }
+
+    public void setExtendedStatistics(boolean extendedStatistics) {
+        this.extendedStatistics = extendedStatistics;
+    }
+
     @Override
     public ClassInfo cacheClass(Class<?> clazz) {
         invoked.incrementAndGet();
@@ -157,22 +166,6 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     }
 
     @Override
-    public Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix) {
-        return IntrospectionSupport.extractProperties(properties, optionPrefix);
-    }
-
-    @Override
-    public Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix, boolean remove) {
-        return IntrospectionSupport.extractProperties(properties, optionPrefix, remove);
-    }
-
-    @Override
-    @Deprecated
-    public Map<String, String> extractStringProperties(Map<String, Object> properties) {
-        return IntrospectionSupport.extractStringProperties(properties);
-    }
-
-    @Override
     @Deprecated
     public boolean setProperties(CamelContext context, TypeConverter typeConverter, Object target, Map<String, Object> properties) throws Exception {
         invoked.incrementAndGet();
diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBeanIntrospectionMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBeanIntrospectionMBean.java
index 0654d19..b9beb31 100644
--- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBeanIntrospectionMBean.java
+++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBeanIntrospectionMBean.java
@@ -24,6 +24,12 @@ public interface ManagedBeanIntrospectionMBean extends ManagedServiceMBean {
     @ManagedAttribute(description = "Number of times bean introspection has been invoked")
     Long getInvokedCounter();
 
+    @ManagedAttribute(description = "Whether to gather extended statistics for introspection usage")
+    Boolean isExtendedStatistics();
+
+    @ManagedAttribute(description = "Whether to gather extended statistics for introspection usage")
+    void setExtendedStatistics(boolean extendedStatistics);
+
     @ManagedOperation(description = "Rests the statistic counters")
     void resetCounters();
 
diff --git a/core/camel-management-impl/src/main/java/org/apache/camel/management/mbean/ManagedBeanIntrospection.java b/core/camel-management-impl/src/main/java/org/apache/camel/management/mbean/ManagedBeanIntrospection.java
index d8205f9..f1e5f5f 100644
--- a/core/camel-management-impl/src/main/java/org/apache/camel/management/mbean/ManagedBeanIntrospection.java
+++ b/core/camel-management-impl/src/main/java/org/apache/camel/management/mbean/ManagedBeanIntrospection.java
@@ -44,6 +44,16 @@ public class ManagedBeanIntrospection extends ManagedService implements ManagedB
     }
 
     @Override
+    public Boolean isExtendedStatistics() {
+        return beanIntrospection.isExtendedStatistics();
+    }
+
+    @Override
+    public void setExtendedStatistics(boolean extendedStatistics) {
+        beanIntrospection.setExtendedStatistics(extendedStatistics);
+    }
+
+    @Override
     public void resetCounters() {
         beanIntrospection.resetCounters();
     }
diff --git a/core/camel-support/src/main/java/org/apache/camel/component/extension/verifier/DefaultComponentVerifierExtension.java b/core/camel-support/src/main/java/org/apache/camel/component/extension/verifier/DefaultComponentVerifierExtension.java
index 66e19f3..ba9b790 100644
--- a/core/camel-support/src/main/java/org/apache/camel/component/extension/verifier/DefaultComponentVerifierExtension.java
+++ b/core/camel-support/src/main/java/org/apache/camel/component/extension/verifier/DefaultComponentVerifierExtension.java
@@ -25,12 +25,12 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Component;
 import org.apache.camel.ComponentAware;
-import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.component.extension.ComponentVerifierExtension;
 import org.apache.camel.runtimecatalog.EndpointValidationResult;
 import org.apache.camel.runtimecatalog.RuntimeCamelCatalog;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.util.PropertiesHelper;
 
 import static org.apache.camel.util.StreamUtils.stream;
 
@@ -194,7 +194,7 @@ public class DefaultComponentVerifierExtension implements ComponentVerifierExten
     }
 
     protected <T> T setProperties(T instance, String prefix, Map<String, Object> properties) throws Exception {
-        return setProperties(instance, getCamelContext().getExtension(ExtendedCamelContext.class).getBeanIntrospection().extractProperties(properties, prefix, false));
+        return setProperties(instance, PropertiesHelper.extractProperties(properties, prefix, false));
     }
 
     protected <T> Optional<T> getOption(Map<String, Object> parameters, String key, Class<T> type) {
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
index e461970..fbcd4ea 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
@@ -43,6 +43,7 @@ import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.PropertyConfigurerAware;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.PropertiesHelper;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
@@ -285,7 +286,7 @@ public abstract class DefaultComponent extends ServiceSupport implements Compone
 
         Map<String, Object> param = parameters;
         if (optionPrefix != null) {
-            param = getCamelContext().getExtension(ExtendedCamelContext.class).getBeanIntrospection().extractProperties(parameters, optionPrefix);
+            param = PropertiesHelper.extractProperties(parameters, optionPrefix);
         }
 
         if (param.size() > 0) {
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
index 72174b6..4248230 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultEndpoint.java
@@ -37,6 +37,7 @@ import org.apache.camel.spi.PropertyConfigurerAware;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.support.service.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.PropertiesHelper;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 
@@ -396,7 +397,7 @@ public abstract class DefaultEndpoint extends ServiceSupport implements Endpoint
 
     @Override
     public void configureProperties(Map<String, Object> options) {
-        Map<String, Object> consumerProperties = getCamelContext().getExtension(ExtendedCamelContext.class).getBeanIntrospection().extractProperties(options, "consumer.");
+        Map<String, Object> consumerProperties = PropertiesHelper.extractProperties(options, "consumer.");
         if (consumerProperties != null && !consumerProperties.isEmpty()) {
             setConsumerProperties(consumerProperties);
         }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
index ba988d5..f214af2 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/IntrospectionSupport.java
@@ -469,10 +469,18 @@ public final class IntrospectionSupport {
         return setProperties(target, properties, optionPrefix, false);
     }
 
+    /**
+     * @deprecated use {@link org.apache.camel.util.PropertiesHelper}
+     */
+    @Deprecated
     public static Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix) {
         return extractProperties(properties, optionPrefix, true);
     }
 
+    /**
+     * @deprecated use {@link org.apache.camel.util.PropertiesHelper}
+     */
+    @Deprecated
     public static Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix, boolean remove) {
         ObjectHelper.notNull(properties, "properties");
 
@@ -495,6 +503,9 @@ public final class IntrospectionSupport {
         return rc;
     }
 
+    /**
+     * @deprecated use {@link org.apache.camel.util.PropertiesHelper}
+     */
     @Deprecated
     public static Map<String, String> extractStringProperties(Map<String, Object> properties) {
         ObjectHelper.notNull(properties, "properties");
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollEndpoint.java b/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollEndpoint.java
index a5d6c98..52c0e05 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollEndpoint.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollEndpoint.java
@@ -29,6 +29,7 @@ import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.spi.PollingConsumerPollStrategy;
 import org.apache.camel.spi.ScheduledPollConsumerScheduler;
 import org.apache.camel.spi.UriParam;
+import org.apache.camel.util.PropertiesHelper;
 
 /**
  * A base class for {@link org.apache.camel.Endpoint} which creates a {@link ScheduledPollConsumer}
@@ -108,7 +109,7 @@ public abstract class ScheduledPollEndpoint extends DefaultEndpoint {
     protected void configureScheduledPollConsumerProperties(Map<String, Object> options, Map<String, Object> consumerProperties) {
         // special for scheduled poll consumers as we want to allow end users to configure its options
         // from the URI parameters without the consumer. prefix
-        Map<String, Object> schedulerProperties = getCamelContext().getExtension(ExtendedCamelContext.class).getBeanIntrospection().extractProperties(options, "scheduler.");
+        Map<String, Object> schedulerProperties = PropertiesHelper.extractProperties(options, "scheduler.");
         if (schedulerProperties != null && !schedulerProperties.isEmpty()) {
             setSchedulerProperties(schedulerProperties);
         }
diff --git a/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java b/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java
new file mode 100644
index 0000000..baa25ee
--- /dev/null
+++ b/core/camel-util/src/main/java/org/apache/camel/util/PropertiesHelper.java
@@ -0,0 +1,69 @@
+/*
+ * 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.camel.util;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public final class PropertiesHelper {
+
+    private PropertiesHelper() {
+    }
+
+    public static Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix) {
+        return extractProperties(properties, optionPrefix, true);
+    }
+
+    public static Map<String, Object> extractProperties(Map<String, Object> properties, String optionPrefix, boolean remove) {
+        ObjectHelper.notNull(properties, "properties");
+
+        Map<String, Object> rc = new LinkedHashMap<>(properties.size());
+
+        for (Iterator<Map.Entry<String, Object>> it = properties.entrySet().iterator(); it.hasNext();) {
+            Map.Entry<String, Object> entry = it.next();
+            String name = entry.getKey();
+            if (name.startsWith(optionPrefix)) {
+                Object value = properties.get(name);
+                name = name.substring(optionPrefix.length());
+                rc.put(name, value);
+
+                if (remove) {
+                    it.remove();
+                }
+            }
+        }
+
+        return rc;
+    }
+
+    @Deprecated
+    public static Map<String, String> extractStringProperties(Map<String, Object> properties) {
+        ObjectHelper.notNull(properties, "properties");
+
+        Map<String, String> rc = new LinkedHashMap<>(properties.size());
+
+        for (Map.Entry<String, Object> entry : properties.entrySet()) {
+            String name = entry.getKey();
+            String value = entry.getValue().toString();
+            rc.put(name, value);
+        }
+
+        return rc;
+    }
+
+}