This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-17571 in repository https://gitbox.apache.org/repos/asf/camel.git
commit a46c8e7c5bcba5f7fb834d48cb9f42b94e8244fd Author: Claus Ibsen <[email protected]> AuthorDate: Fri Mar 11 13:03:30 2022 +0100 CAMEL-17571: camel-jbang - Support for spring @Autowired/@Value annotations in custom beans --- .../apache/camel/spi/CamelBeanPostProcessor.java | 9 +++++ .../camel/spi/CamelBeanPostProcessorInjector.java | 32 +++++++++++++++ .../impl/engine/DefaultCamelBeanPostProcessor.java | 17 ++++++++ dsl/camel-kamelet-main/pom.xml | 10 ++++- .../apache/camel/main/SpringAnnotationSupport.java | 46 ++++++++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) 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 0308f54..1fff611 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 @@ -83,4 +83,13 @@ public interface CamelBeanPostProcessor { return false; } + /** + * Adds a custom bean post injector + * + * @param injector the custom injector + */ + default void addCamelBeanPostProjectInjector(CamelBeanPostProcessorInjector injector) { + // noop + } + } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessorInjector.java b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessorInjector.java new file mode 100644 index 0000000..51febcf --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessorInjector.java @@ -0,0 +1,32 @@ +/* + * 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.spi; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * Used for custom injection when doing {@link CamelBeanPostProcessor} bean post-processing. Can be used to support + * 3rd-party annotations for dependenct injections. + */ +public interface CamelBeanPostProcessorInjector { + + void onFieldInject(Field field, Object bean, String beanName); + + void onFieldMethod(Method method, Object bean, String beanName); + +} diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java index 3a74646..53fab39 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java @@ -37,6 +37,7 @@ import org.apache.camel.Produce; import org.apache.camel.PropertyInject; import org.apache.camel.TypeConverter; import org.apache.camel.spi.CamelBeanPostProcessor; +import org.apache.camel.spi.CamelBeanPostProcessorInjector; import org.apache.camel.spi.Registry; import org.apache.camel.support.DefaultEndpoint; import org.apache.camel.util.ReflectionHelper; @@ -65,6 +66,7 @@ import static org.apache.camel.util.ObjectHelper.isEmpty; public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, CamelContextAware { protected static final Logger LOG = LoggerFactory.getLogger(DefaultCamelBeanPostProcessor.class); + protected final List<CamelBeanPostProcessorInjector> beanPostProcessorInjectors = new ArrayList<>(); protected CamelPostProcessorHelper camelPostProcessorHelper; protected CamelContext camelContext; protected boolean enabled = true; @@ -106,6 +108,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, Ca } @Override + public void addCamelBeanPostProjectInjector(CamelBeanPostProcessorInjector injector) { + this.beanPostProcessorInjectors.add(injector); + } + + @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception { LOG.trace("Camel bean processing before initialization for bean: {}", beanName); @@ -268,6 +275,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, Ca String uri = produce.value().isEmpty() ? produce.uri() : produce.value(); injectField(field, uri, produce.property(), bean, beanName, produce.binding()); } + + // custom bean injector on the field + for (CamelBeanPostProcessorInjector injector : beanPostProcessorInjectors) { + injector.onFieldInject(field, bean, beanName); + } }); } @@ -323,6 +335,11 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, Ca setterInjection(method, bean, beanName); getPostProcessorHelper().consumerInjection(method, bean, beanName); + + // custom bean injector on the method + for (CamelBeanPostProcessorInjector injector : beanPostProcessorInjectors) { + injector.onFieldMethod(method, bean, beanName); + } }); } diff --git a/dsl/camel-kamelet-main/pom.xml b/dsl/camel-kamelet-main/pom.xml index 0236a5f..899e154 100644 --- a/dsl/camel-kamelet-main/pom.xml +++ b/dsl/camel-kamelet-main/pom.xml @@ -113,7 +113,15 @@ <exclusions> <exclusion> <groupId>org.springframework</groupId> - <artifactId>*</artifactId> + <artifactId>spring-aop</artifactId> + </exclusion> + <exclusion> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + </exclusion> + <exclusion> + <groupId>org.springframework</groupId> + <artifactId>spring-expression</artifactId> </exclusion> </exclusions> </dependency> diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java index 26392b0..0f0e8a9 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/SpringAnnotationSupport.java @@ -16,11 +16,20 @@ */ package org.apache.camel.main; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + import org.apache.camel.CamelContext; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.dsl.support.CompilePostProcessor; +import org.apache.camel.impl.engine.CamelPostProcessorHelper; import org.apache.camel.spi.CamelBeanPostProcessor; +import org.apache.camel.spi.CamelBeanPostProcessorInjector; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.ReflectionHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @@ -31,6 +40,8 @@ public final class SpringAnnotationSupport { public static void registerSpringSupport(CamelContext context) { context.getRegistry().bind("SpringAnnotationCompilePostProcessor", new SpringAnnotationCompilePostProcessor()); + context.adapt(ExtendedCamelContext.class).getBeanPostProcessor() + .addCamelBeanPostProjectInjector(new SpringBeanPostProcessorInjector(context)); } private static class SpringAnnotationCompilePostProcessor implements CompilePostProcessor { @@ -62,4 +73,39 @@ public final class SpringAnnotationSupport { } } } + + private static class SpringBeanPostProcessorInjector implements CamelBeanPostProcessorInjector { + + private final CamelContext context; + private final CamelPostProcessorHelper helper; + + public SpringBeanPostProcessorInjector(CamelContext context) { + this.context = context; + this.helper = new CamelPostProcessorHelper(context); + } + + @Override + public void onFieldInject(Field field, Object bean, String beanName) { + Autowired autowired = field.getAnnotation(Autowired.class); + if (autowired != null) { + String name = null; + Qualifier qualifier = field.getAnnotation(Qualifier.class); + if (qualifier != null) { + name = qualifier.value(); + } + ReflectionHelper.setField(field, bean, + helper.getInjectionBeanValue(field.getType(), name)); + } + Value value = field.getAnnotation(Value.class); + if (value != null) { + ReflectionHelper.setField(field, bean, + helper.getInjectionPropertyValue(field.getType(), value.value(), null, null, bean, beanName)); + } + } + + @Override + public void onFieldMethod(Method method, Object bean, String beanName) { + + } + } }
