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 2020/10/12 17:28:55 UTC

[camel] branch master updated: CAMEL-15671: Allow to turn off CamelBeanPostProcessor.

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


The following commit(s) were added to refs/heads/master by this push:
     new 171e424  CAMEL-15671: Allow to turn off CamelBeanPostProcessor.
171e424 is described below

commit 171e4248295238f81bf4b630b0babccdec8972e9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Oct 12 19:07:52 2020 +0200

    CAMEL-15671: Allow to turn off CamelBeanPostProcessor.
---
 .../camel/cdi/xml/CamelContextFactoryBean.java     | 14 ++++
 .../org/apache/camel/spring/camelContext.json      |  1 +
 .../camel/spring/CamelBeanPostProcessor.java       | 10 +++
 .../camel/spring/CamelContextFactoryBean.java      | 25 ++++++++
 .../spring/handler/CamelNamespaceHandler.java      | 12 +++-
 .../SpringBeanPostProcessorDisabledTest.java       | 66 +++++++++++++++++++
 .../spring/SpringBeanPostProcessorEnabledTest.java | 54 ++++++++++++++++
 .../spring/SpringBeanPostProcessorDisabledTest.xml | 36 +++++++++++
 .../spring/SpringBeanPostProcessorEnabledTest.xml  | 36 +++++++++++
 .../apache/camel/spi/CamelBeanPostProcessor.java   | 20 ++++++
 .../camel/impl/engine/AbstractCamelContext.java    |  4 ++
 .../impl/engine/DefaultCamelBeanPostProcessor.java | 24 +++++--
 .../core/xml/AbstractCamelContextFactoryBean.java  |  9 +++
 .../xml/AbstractCamelContextFactoryBeanTest.java   |  4 +-
 .../MainConfigurationPropertiesConfigurer.java     |  5 ++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  1 +
 .../camel/main/DefaultConfigurationConfigurer.java |  1 +
 .../camel/main/DefaultConfigurationProperties.java | 40 ++++++++++++
 .../main/MainIoCBeanPostProcessorDisabledTest.java | 75 ++++++++++++++++++++++
 20 files changed, 430 insertions(+), 8 deletions(-)

diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
index c7b8d35..aaeaf84 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
@@ -69,6 +69,7 @@ import org.apache.camel.model.rest.RestConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformersDefinition;
 import org.apache.camel.model.validator.ValidatorsDefinition;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.PackageScanFilter;
 
 @XmlRootElement(name = "camelContext")
@@ -127,6 +128,10 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     private String useBreadcrumb;
 
     @XmlAttribute
+    @Metadata(defaultValue = "true")
+    private String beanPostProcessorEnabled;
+
+    @XmlAttribute
     private String allowUseOriginalMessage;
 
     @XmlAttribute
@@ -769,6 +774,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     }
 
     @Override
+    public String getBeanPostProcessorEnabled() {
+        return beanPostProcessorEnabled;
+    }
+
+    public void setBeanPostProcessorEnabled(String beanPostProcessorEnabled) {
+        this.beanPostProcessorEnabled = beanPostProcessorEnabled;
+    }
+
+    @Override
     public String getAllowUseOriginalMessage() {
         return allowUseOriginalMessage;
     }
diff --git a/components/camel-spring/src/generated/resources/org/apache/camel/spring/camelContext.json b/components/camel-spring/src/generated/resources/org/apache/camel/spring/camelContext.json
index 98be123..0b445c8 100644
--- a/components/camel-spring/src/generated/resources/org/apache/camel/spring/camelContext.json
+++ b/components/camel-spring/src/generated/resources/org/apache/camel/spring/camelContext.json
@@ -28,6 +28,7 @@
     "mdcLoggingKeysPattern": { "kind": "attribute", "displayName": "MDC Logging Keys Pattern", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets the pattern used for determine which custom MDC keys to propagate during message routing when the routing engine continues routing asynchronously for the given message. Setting this pattern to will propagate all custom keys. Or setting the pattern to foo,bar will propa [...]
     "useDataType": { "kind": "attribute", "displayName": "Use Data Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to enable using data type on Camel messages. Data type are automatic turned on if: one ore more routes has been explicit configured with input and output types when using rest-dsl with binding turned on Otherwise data type is default off." },
     "useBreadcrumb": { "kind": "attribute", "displayName": "Use Breadcrumb", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Set whether breadcrumb is enabled." },
+    "beanPostProcessorEnabled": { "kind": "attribute", "displayName": "Bean Post Processor Enabled", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "defaultValue": "true", "description": "Can be used to turn off bean post processing. Be careful to turn this off, as this means that beans that use Camel annotations such as org.apache.camel.EndpointInject , org.apache.camel.ProducerTemplate , org.apache.camel.Produce , org.apache.c [...]
     "allowUseOriginalMessage": { "kind": "attribute", "displayName": "Allow Use Original Message", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets whether to allow access to the original message from Camel's error handler, or from org.apache.camel.spi.UnitOfWork#getOriginalInMessage() . Turning this off can optimize performance, as defensive copy of the original message is not needed." },
     "caseInsensitiveHeaders": { "kind": "attribute", "displayName": "Case Insensitive Headers", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Whether to use case sensitive or insensitive headers. Important: When using case sensitive (this is set to false). Then the map is case sensitive which means headers such as content-type and Content-Type are two different keys which can be a problem for some protocols such [...]
     "runtimeEndpointRegistryEnabled": { "kind": "attribute", "displayName": "Runtime Endpoint Registry Enabled", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "secret": false, "description": "Sets whether org.apache.camel.spi.RuntimeEndpointRegistry is enabled." },
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
index e1ecb44..d65ab4b 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelBeanPostProcessor.java
@@ -227,4 +227,14 @@ public class CamelBeanPostProcessor
     public void setBindToRegistrySupported(boolean bindToRegistrySupported) {
         this.bindToRegistrySupported = bindToRegistrySupported;
     }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        delegate.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return delegate.isEnabled();
+    }
 }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
index b5878e4..faecac9 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
@@ -146,6 +146,9 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
     @XmlAttribute
     private String useBreadcrumb;
     @XmlAttribute
+    @Metadata(defaultValue = "true")
+    private String beanPostProcessorEnabled;
+    @XmlAttribute
     private String allowUseOriginalMessage;
     @XmlAttribute
     private String caseInsensitiveHeaders;
@@ -948,6 +951,28 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
     }
 
     @Override
+    public String getBeanPostProcessorEnabled() {
+        return beanPostProcessorEnabled;
+    }
+
+    /**
+     * Can be used to turn off bean post processing.
+     *
+     * Be careful to turn this off, as this means that beans that use Camel annotations such as
+     * {@link org.apache.camel.EndpointInject}, {@link org.apache.camel.ProducerTemplate},
+     * {@link org.apache.camel.Produce}, {@link org.apache.camel.Consume} etc will not be injected and in use.
+     *
+     * Turning this off should only be done if you are sure you do not use any of these Camel features.
+     *
+     * Not all runtimes allow turning this off (such as camel-blueprint or camel-cdi with XML).
+     *
+     * The default value is true (enabled).
+     */
+    public void setBeanPostProcessorEnabled(String beanPostProcessorEnabled) {
+        this.beanPostProcessorEnabled = beanPostProcessorEnabled;
+    }
+
+    @Override
     public String getAllowUseOriginalMessage() {
         return allowUseOriginalMessage;
     }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
index 5952d60..01273c7 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
@@ -386,9 +386,10 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
             }
             Object value = parseUsingJaxb(element, parserContext, binder);
 
+            CamelContextFactoryBean factoryBean = null;
             if (value instanceof CamelContextFactoryBean) {
                 // set the property value with the JAXB parsed value
-                CamelContextFactoryBean factoryBean = (CamelContextFactoryBean) value;
+                factoryBean = (CamelContextFactoryBean) value;
                 builder.addPropertyValue("id", contextId);
                 builder.addPropertyValue("implicitId", implicitId);
                 builder.addPropertyValue("restConfiguration", factoryBean.getRestConfiguration());
@@ -468,7 +469,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
 
             // inject bean post processor so we can support @Produce etc.
             // no bean processor element so lets create it by our self
-            injectBeanPostProcessor(element, parserContext, contextId, builder);
+            injectBeanPostProcessor(element, parserContext, contextId, builder, factoryBean);
         }
     }
 
@@ -536,7 +537,8 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
     }
 
     protected void injectBeanPostProcessor(
-            Element element, ParserContext parserContext, String contextId, BeanDefinitionBuilder builder) {
+            Element element, ParserContext parserContext, String contextId, BeanDefinitionBuilder builder,
+            CamelContextFactoryBean factoryBean) {
         Element childElement = element.getOwnerDocument().createElement("beanPostProcessor");
         element.appendChild(childElement);
 
@@ -547,6 +549,10 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
         // otherwise we get a circular reference in spring and it will not allow custom bean post processing
         // see more at CAMEL-1663
         definition.getPropertyValues().addPropertyValue("camelId", contextId);
+        if (factoryBean != null && factoryBean.getBeanPostProcessorEnabled() != null) {
+            // configure early whether bean post processor is enabled or not
+            definition.getPropertyValues().addPropertyValue("enabled", factoryBean.getBeanPostProcessorEnabled());
+        }
         builder.addPropertyReference("beanPostProcessor", beanPostProcessorId);
     }
 
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.java
new file mode 100644
index 0000000..962b03c
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.spring;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class SpringBeanPostProcessorDisabledTest extends SpringTestSupport {
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.xml");
+    }
+
+    @Test
+    public void testDisabled() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(0);
+
+        try {
+            template.sendBody("direct:start", "World");
+            fail("Should throw exception");
+        } catch (CamelExecutionException e) {
+            IllegalArgumentException iae = (IllegalArgumentException) e.getCause();
+            assertEquals("bar is not injected", iae.getMessage());
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public static class MyFoo {
+
+        @Produce("mock:result")
+        private ProducerTemplate bar;
+
+        public void somewhere(String input) {
+            if (bar == null) {
+                throw new IllegalArgumentException("bar is not injected");
+            }
+            bar.sendBody("Hello " + input);
+        }
+
+    }
+
+}
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.java
new file mode 100644
index 0000000..c4f8e3d
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.spring;
+
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class SpringBeanPostProcessorEnabledTest extends SpringTestSupport {
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.xml");
+    }
+
+    @Test
+    public void testEnabled() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedBodiesReceived("Hello World");
+
+        template.sendBody("direct:start", "World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    public static class MyFoo {
+
+        @Produce("mock:result")
+        private ProducerTemplate bar;
+
+        public void somewhere(String input) {
+            bar.sendBody("Hello " + input);
+        }
+
+    }
+
+}
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.xml
new file mode 100644
index 0000000..3be135e
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorDisabledTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+    <bean id="myFoo" class="org.apache.camel.spring.SpringBeanPostProcessorDisabledTest$MyFoo"/>
+
+    <camelContext beanPostProcessorEnabled="false" xmlns="http://camel.apache.org/schema/spring">
+        <route>
+            <from uri="direct:start"/>
+            <bean ref="myFoo" method="somewhere"/>
+        </route>
+    </camelContext>
+
+</beans>
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.xml
new file mode 100644
index 0000000..0f8dae8
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringBeanPostProcessorEnabledTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+    <bean id="myFoo" class="org.apache.camel.spring.SpringBeanPostProcessorDisabledTest$MyFoo"/>
+
+    <camelContext beanPostProcessorEnabled="true" xmlns="http://camel.apache.org/schema/spring">
+        <route>
+            <from uri="direct:start"/>
+            <bean ref="myFoo" method="somewhere"/>
+        </route>
+    </camelContext>
+
+</beans>
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
index 53a9790..3e84b92 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
@@ -51,4 +51,24 @@ public interface CamelBeanPostProcessor {
         return bean;
     }
 
+    /**
+     * Can be used to turn off bean post processing.
+     *
+     * Be careful to turn this off, as this means that beans that use Camel annotations such as
+     * {@link org.apache.camel.EndpointInject}, {@link org.apache.camel.ProducerTemplate},
+     * {@link org.apache.camel.Produce}, {@link org.apache.camel.Consume} etc will not be injected and in use.
+     *
+     * Turning this off should only be done if you are sure you do not use any of these Camel features.
+     */
+    default void setEnabled(boolean enabled) {
+        // noop
+    }
+
+    /**
+     * @see #setEnabled(boolean)
+     */
+    default boolean isEnabled() {
+        return true;
+    }
+
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index a31e126..98fef99 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -2699,6 +2699,10 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     protected void doStartCamel() throws Exception {
+        if (!adapt(ExtendedCamelContext.class).getBeanPostProcessor().isEnabled()) {
+            LOG.info(
+                    "BeanPostProcessor is disabled. This means features such as dependency injection of Camel annotations in beans is not supported.");
+        }
         if (LOG.isDebugEnabled()) {
             LOG.debug(
                     "Using ClassResolver={}, PackageScanClassResolver={}, ApplicationContextClassLoader={}, RouteController={}",
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index 277c2fd..dfd105e 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -68,6 +68,7 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
     protected static final Logger LOG = LoggerFactory.getLogger(DefaultCamelBeanPostProcessor.class);
     protected CamelPostProcessorHelper camelPostProcessorHelper;
     protected CamelContext camelContext;
+    protected boolean enabled = true;
 
     public DefaultCamelBeanPostProcessor() {
     }
@@ -77,6 +78,16 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
     }
 
     @Override
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    @Override
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception {
         LOG.trace("Camel bean processing before initialization for bean: {}", beanName);
 
@@ -85,10 +96,7 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
             return bean;
         }
 
-        // do bean binding on simple types first, and then afterwards on complex types
-        injectFirstPass(bean, beanName, type -> !isComplexUserType(type));
-        injectSecondPass(bean, beanName, type -> isComplexUserType(type));
-
+        // always do injection of camel context
         if (bean instanceof CamelContextAware && canSetCamelContext(bean, beanName)) {
             CamelContextAware contextAware = (CamelContextAware) bean;
             DeferredContextBinding deferredBinding = bean.getClass().getAnnotation(DeferredContextBinding.class);
@@ -101,6 +109,12 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
             }
         }
 
+        if (enabled) {
+            // do bean binding on simple types first, and then afterwards on complex types
+            injectFirstPass(bean, beanName, type -> !isComplexUserType(type));
+            injectSecondPass(bean, beanName, type -> isComplexUserType(type));
+        }
+
         return bean;
     }
 
@@ -118,6 +132,8 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
             defaultEndpoint.setEndpointUriIfNotSpecified(beanName);
         }
 
+        // there is no complex processing so we dont have to check for enabled or disabled
+
         return bean;
     }
 
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 d1aa9fe..bf546a2 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
@@ -91,6 +91,7 @@ import org.apache.camel.processor.interceptor.BacklogTracer;
 import org.apache.camel.reifier.transformer.TransformerReifier;
 import org.apache.camel.reifier.validator.ValidatorReifier;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
+import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.Debugger;
@@ -910,6 +911,8 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
 
     public abstract String getUseBreadcrumb();
 
+    public abstract String getBeanPostProcessorEnabled();
+
     public abstract String getAllowUseOriginalMessage();
 
     public abstract String getCaseInsensitiveHeaders();
@@ -994,6 +997,12 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
      * @throws Exception is thrown if error occurred
      */
     protected void initCamelContext(T context) throws Exception {
+        if (getBeanPostProcessorEnabled() != null) {
+            CamelBeanPostProcessor cbpp = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
+            if (cbpp != null) {
+                cbpp.setEnabled(CamelContextHelper.parseBoolean(context, getBeanPostProcessorEnabled()));
+            }
+        }
         if (getStreamCache() != null) {
             context.setStreamCaching(CamelContextHelper.parseBoolean(context, getStreamCache()));
         }
diff --git a/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java b/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
index 89a759a..0c3a435 100644
--- a/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
+++ b/core/camel-core-xml/src/test/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBeanTest.java
@@ -33,6 +33,7 @@ import org.apache.camel.impl.engine.DefaultClassResolver;
 import org.apache.camel.impl.engine.DefaultFactoryFinder;
 import org.apache.camel.impl.engine.DefaultPackageScanClassResolver;
 import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.spi.CamelBeanPostProcessor;
 import org.apache.camel.spi.ExecutorServiceManager;
 import org.apache.camel.spi.InflightRepository;
 import org.apache.camel.spi.Injector;
@@ -92,7 +93,7 @@ public class AbstractCamelContextFactoryBeanTest {
                     "{{getMessageHistory}}", "{{getLogMask}}", "{{getLogExhaustedMessageBody}}", "{{getHandleFault}}",
                     "{{getCaseInsensitiveHeaders}}",
                     "{{getAutoStartup}}", "{{getUseMDCLogging}}", "{{getUseDataType}}", "{{getUseBreadcrumb}}",
-                    "{{getAllowUseOriginalMessage}}",
+                    "{{getBeanPostProcessorEnabled}}", "{{getAllowUseOriginalMessage}}",
                     "{{getLoadTypeConverters}}", "{{getTypeConverterStatisticsEnabled}}",
                     "{{getInflightRepositoryBrowseEnabled}}"));
 
@@ -135,6 +136,7 @@ public class AbstractCamelContextFactoryBeanTest {
         when(context.getManagementNameStrategy()).thenReturn(mock(ManagementNameStrategy.class));
         when(context.getExecutorServiceManager()).thenReturn(mock(ExecutorServiceManager.class));
         when(context.getInflightRepository()).thenReturn(mock(InflightRepository.class));
+        when(context.getBeanPostProcessor()).thenReturn(mock(CamelBeanPostProcessor.class));
 
         @SuppressWarnings("unchecked")
         final AbstractCamelContextFactoryBean<ModelCamelContext> factory = mock(AbstractCamelContextFactoryBean.class);
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index b64e513..d65b279 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -31,6 +31,7 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         map.put("BacklogTracing", boolean.class);
         map.put("BeanIntrospectionExtendedStatistics", boolean.class);
         map.put("BeanIntrospectionLoggingLevel", org.apache.camel.LoggingLevel.class);
+        map.put("BeanPostProcessorEnabled", boolean.class);
         map.put("CaseInsensitiveHeaders", boolean.class);
         map.put("ConfigurationClasses", java.lang.String.class);
         map.put("Configurations", java.util.List.class);
@@ -134,6 +135,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "BeanIntrospectionExtendedStatistics": target.setBeanIntrospectionExtendedStatistics(property(camelContext, boolean.class, value)); return true;
         case "beanintrospectionlogginglevel":
         case "BeanIntrospectionLoggingLevel": target.setBeanIntrospectionLoggingLevel(property(camelContext, org.apache.camel.LoggingLevel.class, value)); return true;
+        case "beanpostprocessorenabled":
+        case "BeanPostProcessorEnabled": target.setBeanPostProcessorEnabled(property(camelContext, boolean.class, value)); return true;
         case "caseinsensitiveheaders":
         case "CaseInsensitiveHeaders": target.setCaseInsensitiveHeaders(property(camelContext, boolean.class, value)); return true;
         case "configurationclasses":
@@ -313,6 +316,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "BeanIntrospectionExtendedStatistics": return target.isBeanIntrospectionExtendedStatistics();
         case "beanintrospectionlogginglevel":
         case "BeanIntrospectionLoggingLevel": return target.getBeanIntrospectionLoggingLevel();
+        case "beanpostprocessorenabled":
+        case "BeanPostProcessorEnabled": return target.isBeanPostProcessorEnabled();
         case "caseinsensitiveheaders":
         case "CaseInsensitiveHeaders": return target.isCaseInsensitiveHeaders();
         case "configurationclasses":
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 60b10f9..b64d68b 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -23,6 +23,7 @@
     { "name": "camel.main.backlogTracing", "description": "Sets whether backlog tracing is enabled or not. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.beanIntrospectionExtendedStatistics", "description": "Sets whether bean introspection uses extended statistics. The default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.beanIntrospectionLoggingLevel", "description": "Sets the logging level used by bean introspection, logging activity of its usage. The default is TRACE.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] },
+    { "name": "camel.main.beanPostProcessorEnabled", "description": "Can be used to turn off bean post processing. Be careful to turn this off, as this means that beans that use Camel annotations such as org.apache.camel.EndpointInject , org.apache.camel.ProducerTemplate , org.apache.camel.Produce , org.apache.camel.Consume etc will not be injected and in use. Turning this off should only be done if you are sure you do not use any of these Camel features. Not all runtimes allow turning t [...]
     { "name": "camel.main.caseInsensitiveHeaders", "description": "Whether to use case sensitive or insensitive headers. Important: When using case sensitive (this is set to false). Then the map is case sensitive which means headers such as content-type and Content-Type are two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers. However case sensitive implementations can yield faster performance. Therefore use case sensitiv [...]
     { "name": "camel.main.configurationClasses", "description": "Sets classes names that will be used to configure the camel context as example by providing custom beans through org.apache.camel.BindToRegistry annotation.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "string", "javaType": "java.lang.String" },
     { "name": "camel.main.configurations", "description": "Sets the configuration objects used to configure the camel context.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "object", "javaType": "java.util.List" },
diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc
index d213beb..832d6d9 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -35,6 +35,7 @@ The following table lists all the options:
 | *camel.main.backlogTracing* | Sets whether backlog tracing is enabled or not. Default is false. |  | boolean
 | *camel.main.beanIntrospection{zwsp}ExtendedStatistics* | Sets whether bean introspection uses extended statistics. The default is false. |  | boolean
 | *camel.main.beanIntrospection{zwsp}LoggingLevel* | Sets the logging level used by bean introspection, logging activity of its usage. The default is TRACE. |  | LoggingLevel
+| *camel.main.beanPostProcessor{zwsp}Enabled* | Can be used to turn off bean post processing. Be careful to turn this off, as this means that beans that use Camel annotations such as org.apache.camel.EndpointInject , org.apache.camel.ProducerTemplate , org.apache.camel.Produce , org.apache.camel.Consume etc will not be injected and in use. Turning this off should only be done if you are sure you do not use any of these Camel features. Not all runtimes allow turning this off (such as came [...]
 | *camel.main.caseInsensitive{zwsp}Headers* | Whether to use case sensitive or insensitive headers. Important: When using case sensitive (this is set to false). Then the map is case sensitive which means headers such as content-type and Content-Type are two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers. However case sensitive implementations can yield faster performance. Therefore use case sensitive implementation with [...]
 | *camel.main.configuration{zwsp}Classes* | Sets classes names that will be used to configure the camel context as example by providing custom beans through org.apache.camel.BindToRegistry annotation. |  | String
 | *camel.main.configurations* | Sets the configuration objects used to configure the camel context. |  | List
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 9f36324..28e32ff 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
@@ -89,6 +89,7 @@ public final class DefaultConfigurationConfigurer {
      */
     public static void configure(CamelContext camelContext, DefaultConfigurationProperties config) throws Exception {
         ExtendedCamelContext ecc = camelContext.adapt(ExtendedCamelContext.class);
+        ecc.getBeanPostProcessor().setEnabled(config.isBeanPostProcessorEnabled());
         ecc.getBeanIntrospection().setExtendedStatistics(config.isBeanIntrospectionExtendedStatistics());
         if (config.getBeanIntrospectionLoggingLevel() != null) {
             ecc.getBeanIntrospection().setLoggingLevel(config.getBeanIntrospectionLoggingLevel());
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 37d3a59..5939748 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
@@ -68,6 +68,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean endpointBasicPropertyBinding;
     private boolean useDataType;
     private boolean useBreadcrumb;
+    private boolean beanPostProcessorEnabled = true;
     @Metadata(defaultValue = "Default")
     private ManagementStatisticsLevel jmxManagementStatisticsLevel = ManagementStatisticsLevel.Default;
     private String jmxManagementNamePattern = "#name#";
@@ -642,6 +643,27 @@ public abstract class DefaultConfigurationProperties<T> {
         this.useBreadcrumb = useBreadcrumb;
     }
 
+    public boolean isBeanPostProcessorEnabled() {
+        return beanPostProcessorEnabled;
+    }
+
+    /**
+     * Can be used to turn off bean post processing.
+     *
+     * Be careful to turn this off, as this means that beans that use Camel annotations such as
+     * {@link org.apache.camel.EndpointInject}, {@link org.apache.camel.ProducerTemplate},
+     * {@link org.apache.camel.Produce}, {@link org.apache.camel.Consume} etc will not be injected and in use.
+     *
+     * Turning this off should only be done if you are sure you do not use any of these Camel features.
+     *
+     * Not all runtimes allow turning this off (such as camel-blueprint or camel-cdi with XML).
+     *
+     * The default value is true (enabled).
+     */
+    public void setBeanPostProcessorEnabled(boolean beanPostProcessorEnabled) {
+        this.beanPostProcessorEnabled = beanPostProcessorEnabled;
+    }
+
     public ManagementStatisticsLevel getJmxManagementStatisticsLevel() {
         return jmxManagementStatisticsLevel;
     }
@@ -1483,6 +1505,24 @@ public abstract class DefaultConfigurationProperties<T> {
     }
 
     /**
+     * Can be used to turn off bean post processing.
+     *
+     * Be careful to turn this off, as this means that beans that use Camel annotations such as
+     * {@link org.apache.camel.EndpointInject}, {@link org.apache.camel.ProducerTemplate},
+     * {@link org.apache.camel.Produce}, {@link org.apache.camel.Consume} etc will not be injected and in use.
+     *
+     * Turning this off should only be done if you are sure you do not use any of these Camel features.
+     *
+     * Not all runtimes allow turning this off (such as camel-blueprint or camel-cdi with XML).
+     *
+     * The default value is true (enabled).
+     */
+    public T withBeanPostProcessorEnabled(boolean beanPostProcessorEnabled) {
+        this.beanPostProcessorEnabled = beanPostProcessorEnabled;
+        return (T) this;
+    }
+
+    /**
      * Sets the JMX statistics level The level can be set to Extended to gather additional information
      *
      * The default value is Default.
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/MainIoCBeanPostProcessorDisabledTest.java b/core/camel-main/src/test/java/org/apache/camel/main/MainIoCBeanPostProcessorDisabledTest.java
new file mode 100644
index 0000000..663b246
--- /dev/null
+++ b/core/camel-main/src/test/java/org/apache/camel/main/MainIoCBeanPostProcessorDisabledTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.main;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.CamelContext;
+import org.apache.camel.FailedToCreateRouteException;
+import org.apache.camel.NoSuchBeanException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class MainIoCBeanPostProcessorDisabledTest {
+
+    @Test
+    public void testMainIoCEnabled() throws Exception {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new MyRouteBuilder());
+        main.start();
+
+        CamelContext camelContext = main.getCamelContext();
+        assertNotNull(camelContext);
+
+        MockEndpoint endpoint = camelContext.getEndpoint("mock:results", MockEndpoint.class);
+        endpoint.expectedBodiesReceived("tony");
+
+        main.getCamelTemplate().sendBody("direct:start", "<message>1</message>");
+
+        endpoint.assertIsSatisfied();
+
+        main.stop();
+    }
+
+    @Test
+    public void testMainIoCDisabled() throws Exception {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new MyRouteBuilder());
+        main.configure().withBeanPostProcessorEnabled(false);
+
+        try {
+            main.start();
+            fail("Should throw exception");
+        } catch (FailedToCreateRouteException e) {
+            NoSuchBeanException nsbe = (NoSuchBeanException) e.getCause();
+            assertEquals("tiger", nsbe.getName());
+        }
+    }
+
+    public static class MyRouteBuilder extends RouteBuilder {
+
+        @BindToRegistry("tiger")
+        public String String = "tony";
+
+        @Override
+        public void configure() throws Exception {
+            from("direct:start").bean("tiger", "toString").to("mock:results");
+        }
+    }
+}