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 <[email protected]>
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");
+ }
+ }
+}