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/24 16:58:08 UTC

[camel] branch master updated (98748e7 -> 923f855)

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

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


    from 98748e7  Camel-Salesforce: Fix serialization for string MPLs
     new b9e55dd  CAMEL-13870: Generating fast component options configurer
     new 5c1f582  CAMEL-13870: Generating fast component options configurer
     new 923f855  CAMEL-13870: Add @SuppressWarnings to generated configurer.

The 3 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:
 .../src/main/docs/properties-component.adoc        |   3 +-
 .../component/properties/PropertiesComponent.java  |  16 ++-
 .../src/main/java/org/apache/camel/Component.java  |   9 ++
 .../component/log/LogComponentOptionsTest.java     | 146 +++++++++++++++++++++
 .../org/apache/camel/support/DefaultComponent.java |  19 ++-
 .../org/apache/camel/support/DefaultEndpoint.java  |   4 +-
 .../camel/support/PropertyBindingSupport.java      |   9 +-
 .../PropertiesComponentConfiguration.java          |  15 ---
 .../apt/ComponentPropertyConfigurerGenerator.java  |   1 +
 .../tools/apt/EndpointAnnotationProcessor.java     |  85 ++++++++----
 .../apt/EndpointPropertyConfigurerGenerator.java   |   1 +
 .../main/java/org/apache/camel/spi/Metadata.java   |   5 +
 12 files changed, 266 insertions(+), 47 deletions(-)
 create mode 100644 core/camel-core/src/test/java/org/apache/camel/component/log/LogComponentOptionsTest.java


[camel] 03/03: CAMEL-13870: Add @SuppressWarnings to generated configurer.

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

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

commit 923f8558db0f2447e72f0f9adcc8a0d98a7d0d6a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Aug 24 18:32:43 2019 +0200

    CAMEL-13870: Add @SuppressWarnings to generated configurer.
---
 .../org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java | 1 +
 .../org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java
index 4f9474b..9bfb41e 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/ComponentPropertyConfigurerGenerator.java
@@ -90,6 +90,7 @@ public final class ComponentPropertyConfigurerGenerator {
             w.write("/**\n");
             w.write(" * Source code generated by org.apache.camel:apt\n");
             w.write(" */\n");
+            w.write("@SuppressWarnings(\"unchecked\")\n");
             w.write("public class " + cn + " extends PropertyConfigurerSupport implements TriPropertyConfigurer {\n");
             w.write("\n");
             w.write("    private static final Map<String, TriConsumer<CamelContext, Object, Object>> WRITES;\n");
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
index abb81ee..a8c5dcc 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointPropertyConfigurerGenerator.java
@@ -89,6 +89,7 @@ public final class EndpointPropertyConfigurerGenerator {
             w.write("/**\n");
             w.write(" * Source code generated by org.apache.camel:apt\n");
             w.write(" */\n");
+            w.write("@SuppressWarnings(\"unchecked\")\n");
             w.write("public class " + cn + " extends PropertyConfigurerSupport implements TriPropertyConfigurer {\n");
             w.write("\n");
             w.write("    private static final Map<String, TriConsumer<CamelContext, Object, Object>> WRITES;\n");


[camel] 02/03: CAMEL-13870: Generating fast component options configurer

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

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

commit 5c1f5820f456a7e4b32587a2d1aa6eb05c4e6a62
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Aug 24 16:35:30 2019 +0200

    CAMEL-13870: Generating fast component options configurer
---
 .../src/main/docs/properties-component.adoc               |  3 +--
 .../camel/component/properties/PropertiesComponent.java   |  6 +++---
 .../camel/core/xml/AbstractCamelContextFactoryBean.java   |  2 +-
 .../springboot/PropertiesComponentConfiguration.java      | 15 ---------------
 .../camel/tools/apt/EndpointAnnotationProcessor.java      | 10 ++++++++++
 .../src/main/java/org/apache/camel/spi/Metadata.java      |  5 +++++
 6 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/components/camel-properties/src/main/docs/properties-component.adoc b/components/camel-properties/src/main/docs/properties-component.adoc
index 2b9fcdd..d542d8d 100644
--- a/components/camel-properties/src/main/docs/properties-component.adoc
+++ b/components/camel-properties/src/main/docs/properties-component.adoc
@@ -15,14 +15,13 @@ Where *key* is the key for the property to lookup
 == Options
 
 // component options: START
-The Properties component supports 12 options, which are listed below.
+The Properties component supports 11 options, which are listed below.
 
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *locations* (common) | A list of locations to load properties. This option will override any default locations and only use the locations from this option. |  | List
 | *location* (common) | A list of locations to load properties. You can use comma to separate multiple locations. This option will override any default locations and only use the locations from this option. |  | String
 | *encoding* (common) | Encoding to use when loading properties file from the file system or classpath. If no encoding has been set, then the properties files is loaded using ISO-8859-1 encoding (latin-1) as documented by java.util.Properties#load(java.io.InputStream) |  | String
 | *propertiesParser* (common) | To use a custom PropertiesParser |  | PropertiesParser
diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 1613bab..8b83d12 100644
--- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -106,8 +106,8 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
     private PropertiesParser propertiesParser = new DefaultPropertiesParser(this);
     private final PropertiesLookup propertiesLookup = new DefaultPropertiesLookup(this);
     private final List<PropertiesSource> sources = new ArrayList<>();
-    private List<PropertiesLocation> locations = Collections.emptyList();
-
+    @Metadata(skip = true)
+    private List<PropertiesLocation> locations = new ArrayList<>();
     @Metadata
     private String location;
     @Metadata
@@ -283,7 +283,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
      * A list of locations to load properties.
      * This option will override any default locations and only use the locations from this option.
      */
-    private void setLocations(List<PropertiesLocation> locations) {
+    public void setLocations(List<PropertiesLocation> locations) {
         // reset locations
         locations = parseLocations(locations);
         this.locations = Collections.unmodifiableList(locations);
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index abdbbd2..8fbc61d 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -627,7 +627,7 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
             }
 
             PropertiesComponent pc = new PropertiesComponent();
-            locations.forEach(pc::addLocation);
+            pc.setLocations(locations);
             pc.setEncoding(def.getEncoding());
 
             if (def.isIgnoreMissingLocation() != null) {
diff --git a/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java
index 5a0d072..ad7ad86 100644
--- a/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-properties-starter/src/main/java/org/apache/camel/component/properties/springboot/PropertiesComponentConfiguration.java
@@ -16,9 +16,7 @@
  */
 package org.apache.camel.component.properties.springboot;
 
-import java.util.List;
 import javax.annotation.Generated;
-import org.apache.camel.component.properties.PropertiesLocation;
 import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 
@@ -40,11 +38,6 @@ public class PropertiesComponentConfiguration
      */
     private Boolean enabled;
     /**
-     * A list of locations to load properties. This option will override any
-     * default locations and only use the locations from this option.
-     */
-    private List<PropertiesLocation> locations;
-    /**
      * A list of locations to load properties. You can use comma to separate
      * multiple locations. This option will override any default locations and
      * only use the locations from this option.
@@ -108,14 +101,6 @@ public class PropertiesComponentConfiguration
      */
     private Boolean basicPropertyBinding = false;
 
-    public List<PropertiesLocation> getLocations() {
-        return locations;
-    }
-
-    public void setLocations(List<PropertiesLocation> locations) {
-        this.locations = locations;
-    }
-
     public String getLocation() {
         return location;
     }
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
index bd396e1..4d7621b 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
@@ -552,6 +552,10 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
                 String methodName = method.getSimpleName().toString();
                 boolean deprecated = method.getAnnotation(Deprecated.class) != null;
                 Metadata metadata = method.getAnnotation(Metadata.class);
+                if (metadata != null && metadata.skip()) {
+                    continue;
+                }
+
                 String deprecationNote = null;
                 if (metadata != null) {
                     deprecationNote = metadata.deprecationNote();
@@ -580,6 +584,9 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
                 if (field != null && metadata == null) {
                     metadata = field.getAnnotation(Metadata.class);
                 }
+                if (metadata != null && metadata.skip()) {
+                    continue;
+                }
 
                 boolean required = metadata != null && metadata.required();
                 String label = metadata != null ? metadata.label() : null;
@@ -676,6 +683,9 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
             for (VariableElement fieldElement : fieldElements) {
 
                 Metadata metadata = fieldElement.getAnnotation(Metadata.class);
+                if (metadata != null && metadata.skip()) {
+                    continue;
+                }
                 boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != null;
                 String deprecationNote = null;
                 if (metadata != null) {
diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
index 60de377..873952d 100644
--- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
+++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
@@ -100,4 +100,9 @@ public @interface Metadata {
      */
     String deprecationNote() default "";
 
+    /**
+     * Whether to skip this option
+     */
+    boolean skip() default false;
+
 }


[camel] 01/03: CAMEL-13870: Generating fast component options configurer

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

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

commit b9e55dd08891dc50141d1d94953af445db214e4b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Aug 24 16:30:10 2019 +0200

    CAMEL-13870: Generating fast component options configurer
---
 .../component/properties/PropertiesComponent.java  |  14 +-
 .../src/main/java/org/apache/camel/Component.java  |   9 ++
 .../core/xml/AbstractCamelContextFactoryBean.java  |   2 +-
 .../component/log/LogComponentOptionsTest.java     | 146 +++++++++++++++++++++
 .../org/apache/camel/support/DefaultComponent.java |  19 ++-
 .../org/apache/camel/support/DefaultEndpoint.java  |   4 +-
 .../camel/support/PropertyBindingSupport.java      |   9 +-
 .../tools/apt/EndpointAnnotationProcessor.java     |  75 +++++++----
 8 files changed, 248 insertions(+), 30 deletions(-)

diff --git a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 13f57de..1613bab 100644
--- a/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ b/components/camel-properties/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -106,10 +106,11 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
     private PropertiesParser propertiesParser = new DefaultPropertiesParser(this);
     private final PropertiesLookup propertiesLookup = new DefaultPropertiesLookup(this);
     private final List<PropertiesSource> sources = new ArrayList<>();
-
     private List<PropertiesLocation> locations = Collections.emptyList();
 
     @Metadata
+    private String location;
+    @Metadata
     private boolean ignoreMissingLocation;
     @Metadata
     private String encoding;
@@ -282,7 +283,7 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
      * A list of locations to load properties.
      * This option will override any default locations and only use the locations from this option.
      */
-    public void setLocations(List<PropertiesLocation> locations) {
+    private void setLocations(List<PropertiesLocation> locations) {
         // reset locations
         locations = parseLocations(locations);
         this.locations = Collections.unmodifiableList(locations);
@@ -324,6 +325,10 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
         setLocations(locations);
     }
 
+    public void addLocation(PropertiesLocation location) {
+        this.locations.add(location);
+    }
+
     @Override
     public void addLocation(String location) {
         if (location != null) {
@@ -345,11 +350,16 @@ public class PropertiesComponent extends DefaultComponent implements org.apache.
      */
     @Override
     public void setLocation(String location) {
+        this.location = location;
         if (location != null) {
             setLocations(location.split(","));
         }
     }
 
+    public String getLocation() {
+        return location;
+    }
+
     @ManagedAttribute(description = "Encoding to use when loading properties file from the file system or classpath")
     public String getEncoding() {
         return encoding;
diff --git a/core/camel-api/src/main/java/org/apache/camel/Component.java b/core/camel-api/src/main/java/org/apache/camel/Component.java
index 32683c8..809c90e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Component.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Component.java
@@ -73,6 +73,15 @@ public interface Component extends CamelContextAware, Service {
     boolean useRawUri();
 
     /**
+     * Gets the component {@link PropertyConfigurer}.
+     *
+     * @return the configurer, or <tt>null</tt> if the component does not support using property configurer.
+     */
+    default PropertyConfigurer getComponentPropertyConfigurer() {
+        return null;
+    }
+
+    /**
      * Gets the endpoint {@link PropertyConfigurer}.
      *
      * @return the configurer, or <tt>null</tt> if the endpoint does not support using property configurer.
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 8fbc61d..abdbbd2 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -627,7 +627,7 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
             }
 
             PropertiesComponent pc = new PropertiesComponent();
-            pc.setLocations(locations);
+            locations.forEach(pc::addLocation);
             pc.setEncoding(def.getEncoding());
 
             if (def.isIgnoreMissingLocation() != null) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/log/LogComponentOptionsTest.java b/core/camel-core/src/test/java/org/apache/camel/component/log/LogComponentOptionsTest.java
new file mode 100644
index 0000000..df492e1
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/component/log/LogComponentOptionsTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.component.log;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.processor.DefaultExchangeFormatter;
+import org.junit.Test;
+
+public class LogComponentOptionsTest extends ContextTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testFastLogComponentOptions() throws Exception {
+        context.start();
+
+        long before = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        DefaultExchangeFormatter myFormatter = new DefaultExchangeFormatter();
+
+        LogComponent log = context.getComponent("log", LogComponent.class);
+        assertNull(log.getExchangeFormatter());
+
+        new PropertyBindingSupport.Builder().withCamelContext(context).withTarget(log)
+                .withConfigurer(log.getComponentPropertyConfigurer())
+                .withProperty("exchangeFormatter", myFormatter).bind();
+
+        assertSame(myFormatter, log.getExchangeFormatter());
+
+        long after = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        assertEquals("Should not use Java reflection", before, after);
+    }
+
+    @Test
+    public void testFastLogComponentNestedOptions() throws Exception {
+        context.start();
+
+        long before = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        DefaultExchangeFormatter myFormatter = new DefaultExchangeFormatter();
+
+        LogComponent log = context.getComponent("log", LogComponent.class);
+        assertNull(log.getExchangeFormatter());
+
+        new PropertyBindingSupport.Builder().withCamelContext(context).withTarget(log)
+                .withConfigurer(log.getComponentPropertyConfigurer())
+                .withProperty("exchangeFormatter", myFormatter)
+                .withProperty("exchangeFormatter.showExchangeId", "true").bind();
+
+        assertSame(myFormatter, log.getExchangeFormatter());
+
+        long after = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        assertTrue("Should use Java reflection", after > before);
+    }
+
+    @Test
+    public void testFastLogComponentOptionsLookupRegistry() throws Exception {
+        context.start();
+
+        long before = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        DefaultExchangeFormatter myFormatter = new DefaultExchangeFormatter();
+        context.getRegistry().bind("myGreatFormatter", myFormatter);
+
+        LogComponent log = context.getComponent("log", LogComponent.class);
+        assertNull(log.getExchangeFormatter());
+
+        new PropertyBindingSupport.Builder().withCamelContext(context).withTarget(log)
+                .withConfigurer(log.getComponentPropertyConfigurer())
+                .withProperty("exchangeFormatter", "#bean:myGreatFormatter").bind();
+
+        assertSame(myFormatter, log.getExchangeFormatter());
+
+        long after = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        assertEquals("Should not use Java reflection", before, after);
+    }
+
+    @Test
+    public void testSlowLogComponentOptions() throws Exception {
+        context.start();
+
+        long before = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        DefaultExchangeFormatter myFormatter = new DefaultExchangeFormatter();
+
+        LogComponent log = context.getComponent("log", LogComponent.class);
+        assertNull(log.getExchangeFormatter());
+
+        new PropertyBindingSupport.Builder().withCamelContext(context).withTarget(log)
+                .withProperty("exchangeFormatter", myFormatter)
+                .withProperty("exchangeFormatter.showExchangeId", "true").bind();
+
+        assertSame(myFormatter, log.getExchangeFormatter());
+        assertTrue(myFormatter.isShowExchangeId());
+
+        long after = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        assertTrue("Should use reflection", after > before);
+    }
+
+    @Test
+    public void testSlowLogComponentOptionsLookupRegistry() throws Exception {
+        context.start();
+
+        long before = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        DefaultExchangeFormatter myFormatter = new DefaultExchangeFormatter();
+        context.getRegistry().bind("myGreatFormatter", myFormatter);
+
+        LogComponent log = context.getComponent("log", LogComponent.class);
+        assertNull(log.getExchangeFormatter());
+
+        new PropertyBindingSupport.Builder().withCamelContext(context).withTarget(log)
+                .withProperty("exchangeFormatter", "#bean:myGreatFormatter")
+                .withProperty("exchangeFormatter.showExchangeId", "true").bind();
+
+        assertSame(myFormatter, log.getExchangeFormatter());
+        assertTrue(myFormatter.isShowExchangeId());
+
+        long after = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().getInvokedCounter();
+
+        assertTrue("Should use reflection", after > before);
+    }
+}
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 d7fc017..4c6aa71 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
@@ -59,6 +59,7 @@ public abstract class DefaultComponent extends ServiceSupport implements Compone
 
     private static final String RESOURCE_PATH = "META-INF/services/org/apache/camel/configurer/";
 
+    private volatile TriPropertyConfigurer componentPropertyConfigurer;
     private volatile TriPropertyConfigurer endpointPropertyConfigurer;
     private final List<Supplier<ComponentExtension>> extensions = new ArrayList<>();
     private CamelContext camelContext;
@@ -339,8 +340,15 @@ public abstract class DefaultComponent extends ServiceSupport implements Compone
                 name = StringHelper.before(name, ",");
             }
             try {
-                log.trace("Discovering optional endpoint property configurer class for component: {}", name);
+                log.trace("Discovering optional component property configurer class for component: {}", name);
                 Optional<Class<?>> clazz = getCamelContext().adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH)
+                        .findOptionalClass(name + "-component", null);
+                clazz.ifPresent(c -> componentPropertyConfigurer = org.apache.camel.support.ObjectHelper.newInstance(c, TriPropertyConfigurer.class));
+                if (log.isDebugEnabled() && componentPropertyConfigurer != null) {
+                    log.debug("Discovered component property configurer: {} -> {}", name, componentPropertyConfigurer);
+                }
+                log.trace("Discovering optional endpoint property configurer class for component: {}", name);
+                clazz = getCamelContext().adapt(ExtendedCamelContext.class).getFactoryFinder(RESOURCE_PATH)
                         .findOptionalClass(name + "-endpoint", null);
                 clazz.ifPresent(c -> endpointPropertyConfigurer = org.apache.camel.support.ObjectHelper.newInstance(c, TriPropertyConfigurer.class));
                 if (log.isDebugEnabled() && endpointPropertyConfigurer != null) {
@@ -407,7 +415,9 @@ public abstract class DefaultComponent extends ServiceSupport implements Compone
                     .bind(camelContext, bean, parameters);
         } else {
             PropertyConfigurer configurer = null;
-            if (bean instanceof Endpoint) {
+            if (bean instanceof Component) {
+                configurer = getComponentPropertyConfigurer();
+            } else if (bean instanceof Endpoint) {
                 configurer = getEndpointPropertyConfigurer();
             } else if (bean instanceof PropertyConfigurerAware) {
                 configurer = ((PropertyConfigurerAware) bean).getPropertyConfigurer(bean);
@@ -418,6 +428,11 @@ public abstract class DefaultComponent extends ServiceSupport implements Compone
     }
 
     @Override
+    public PropertyConfigurer getComponentPropertyConfigurer() {
+        return componentPropertyConfigurer;
+    }
+
+    @Override
     public PropertyConfigurer getEndpointPropertyConfigurer() {
         return endpointPropertyConfigurer;
     }
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 2041a5f..ff7b490 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
@@ -423,7 +423,9 @@ public abstract class DefaultEndpoint extends ServiceSupport implements Endpoint
                     .bind(camelContext, bean, parameters);
         } else {
             PropertyConfigurer configurer = null;
-            if (bean instanceof Endpoint) {
+            if (bean instanceof Component) {
+                configurer = getComponent().getComponentPropertyConfigurer();
+            } else if (bean instanceof Endpoint) {
                 configurer = getComponent().getEndpointPropertyConfigurer();
             } else if (bean instanceof PropertyConfigurerAware) {
                 configurer = ((PropertyConfigurerAware) bean).getPropertyConfigurer(bean);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
index bdce66f..f45f557 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java
@@ -465,7 +465,12 @@ public final class PropertyBindingSupport {
                 Map.Entry<String, Object> entry = iter.next();
                 String key = entry.getKey();
                 Object value = entry.getValue();
-                if (writeProperties.containsKey(key)) {
+                boolean valid = true;
+                if (nesting) {
+                    // property configurer does not support nested names so skip if the name has a dot
+                    valid = key.indexOf('.') == -1;
+                }
+                if (valid && writeProperties.containsKey(key)) {
                     writeProperties.get(key).accept(camelContext, target, value);
                     if (removeParameter) {
                         iter.remove();
@@ -641,6 +646,8 @@ public final class PropertyBindingSupport {
             }
         }
 
+        // TODO: Move configurer here so the value can have done all its magic
+
         boolean hit = context.adapt(ExtendedCamelContext.class).getBeanIntrospection().setProperty(context, context.getTypeConverter(), target, name, value, refName, fluentBuilder, allowPrivateSetter, ignoreCase);
         if (!hit && mandatory) {
             // there is no setter with this given name, so lets report this as a problem
diff --git a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
index 8d7d7d6..bd396e1 100644
--- a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
+++ b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
@@ -163,39 +163,70 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
             }
         }
 
+        // component options
         TypeElement componentClassElement = findTypeElement(processingEnv, roundEnv, componentModel.getJavaType());
         if (componentClassElement != null) {
             findComponentClassProperties(writer, roundEnv, componentModel, componentOptions, componentClassElement, "", parentData, null, null);
         }
+        generateComponentConfigurer(roundEnv, uriEndpoint, scheme, schemes, componentModel, componentOptions);
 
+        // endpoint options
         findClassProperties(writer, roundEnv, componentModel, endpointPaths, endpointOptions, classElement, "", uriEndpoint.excludeProperties(), parentData, null, null);
-
         String json = createParameterJsonSchema(componentModel, componentOptions, endpointPaths, endpointOptions, schemes, parentData);
         writer.println(json);
+        generateEndpointConfigurer(roundEnv, classElement, uriEndpoint, scheme, schemes, componentModel, endpointOptions);
+    }
 
-        // special for activemq and amqp scheme which should reuse jms
+    private void generateComponentConfigurer(RoundEnvironment roundEnv, UriEndpoint uriEndpoint, String scheme, String[] schemes,
+                                             ComponentModel componentModel, Set<ComponentOption> componentOptions) {
+        TypeElement parent;
         if ("activemq".equals(scheme) || "amqp".equals(scheme)) {
-            TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.component.jms.JmsEndpointConfigurer");
-            String fqen = classElement.getQualifiedName().toString();
-            String pn = fqen.substring(0, fqen.lastIndexOf('.'));
-            String en = classElement.getSimpleName().toString();
-            String cn = en + "Configurer";
-            String fqn = pn + "." + cn;
-
-            EndpointPropertyConfigurerGenerator.generateExtendConfigurer(processingEnv, parent, pn, cn, fqn);
-            EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqn);
-        } else if (uriEndpoint.generateConfigurer() && !endpointOptions.isEmpty()) {
-            TypeElement parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.spi.TriPropertyConfigurer");
-            String fqen = classElement.getQualifiedName().toString();
-            String pn = fqen.substring(0, fqen.lastIndexOf('.'));
-            String en = classElement.getSimpleName().toString();
-            String cn = en + "Configurer";
-            String fqn = pn + "." + cn;
+            // special for activemq and amqp scheme which should reuse jms
+            parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.component.jms.JmsComponentConfigurer");
+        } else {
+            parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.spi.TriPropertyConfigurer");
+        }
+        String fqComponentClassName = componentModel.getJavaType();
+        String componentClassName = fqComponentClassName.substring(fqComponentClassName.lastIndexOf('.') + 1);
+        String className = componentClassName + "Configurer";
+        String packageName = fqComponentClassName.substring(0, fqComponentClassName.lastIndexOf('.'));
+        String fqClassName = packageName + "." + className;
 
+        if ("activemq".equals(scheme) || "amqp".equals(scheme)) {
+            ComponentPropertyConfigurerGenerator.generateExtendConfigurer(processingEnv, parent, packageName, className, fqClassName);
+            ComponentPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-component", fqClassName);
+        } else if (uriEndpoint.generateConfigurer() && !componentOptions.isEmpty()) {
             // only generate this once for the first scheme
             if (schemes == null || schemes[0].equals(scheme)) {
-                EndpointPropertyConfigurerGenerator.generatePropertyConfigurer(processingEnv, parent, pn, cn, fqn, en, endpointOptions);
-                EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqn);
+                ComponentPropertyConfigurerGenerator.generatePropertyConfigurer(processingEnv, parent, packageName, className, fqClassName, componentClassName, componentOptions);
+                ComponentPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-component", fqClassName);
+            }
+        }
+    }
+
+    private void generateEndpointConfigurer(RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint, String scheme, String[] schemes,
+                                            ComponentModel componentModel, Set<EndpointOption> endpointOptions) {
+        TypeElement parent;
+        if ("activemq".equals(scheme) || "amqp".equals(scheme)) {
+            // special for activemq and amqp scheme which should reuse jms
+            parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.component.jms.JmsEndpointConfigurer");
+        } else {
+            parent = findTypeElement(processingEnv, roundEnv, "org.apache.camel.spi.TriPropertyConfigurer");
+        }
+        String fqEndpointClassName = classElement.getQualifiedName().toString();
+        String packageName = fqEndpointClassName.substring(0, fqEndpointClassName.lastIndexOf('.'));
+        String endpointClassName = classElement.getSimpleName().toString();
+        String className = endpointClassName + "Configurer";
+        String fqClassName = packageName + "." + className;
+
+        if ("activemq".equals(scheme) || "amqp".equals(scheme)) {
+            EndpointPropertyConfigurerGenerator.generateExtendConfigurer(processingEnv, parent, packageName, className, fqClassName);
+            EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqClassName);
+        } else if (uriEndpoint.generateConfigurer() && !endpointOptions.isEmpty()) {
+            // only generate this once for the first scheme
+            if (schemes == null || schemes[0].equals(scheme)) {
+                EndpointPropertyConfigurerGenerator.generatePropertyConfigurer(processingEnv, parent, packageName, className, fqClassName, endpointClassName, endpointOptions);
+                EndpointPropertyConfigurerGenerator.generateMetaInfConfigurer(processingEnv, componentModel.getScheme() + "-endpoint", fqClassName);
             }
         }
     }
@@ -542,11 +573,9 @@ public class EndpointAnnotationProcessor extends AbstractCamelAnnotationProcesso
                     continue;
                 }
 
-                // must be a getter/setter pair
+                // we usually favor putting the @Metadata annotation on the field instead of the setter, so try to use it if its there
                 String fieldName = methodName.substring(3);
                 fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
-
-                // we usually favor putting the @Metadata annotation on the field instead of the setter, so try to use it if its there
                 VariableElement field = findFieldElement(classElement, fieldName);
                 if (field != null && metadata == null) {
                     metadata = field.getAnnotation(Metadata.class);