You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2016/04/19 14:58:56 UTC

[4/6] camel git commit: CAMEL-9882: Support importing Camel XML configuration files in Camel CDI

CAMEL-9882: Support importing Camel XML configuration files in Camel CDI


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/ba1172ad
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/ba1172ad
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/ba1172ad

Branch: refs/heads/master
Commit: ba1172adca9a61827fb7f115d728d091ba96c503
Parents: 3e0795c
Author: Antonin Stefanutti <an...@stefanutti.fr>
Authored: Mon Apr 18 17:31:29 2016 +0200
Committer: Antonin Stefanutti <an...@stefanutti.fr>
Committed: Tue Apr 19 14:49:35 2016 +0200

----------------------------------------------------------------------
 components/camel-cdi/pom.xml                    |  11 +
 .../camel/cdi/ApplicationScopedLiteral.java     |  31 +
 .../org/apache/camel/cdi/BeanManagerHelper.java |   5 +-
 .../camel/cdi/CamelContextDefaultProducer.java  |  55 --
 .../camel/cdi/CdiCamelContextAnnotated.java     |  65 --
 .../apache/camel/cdi/CdiCamelContextBean.java   | 120 ----
 .../org/apache/camel/cdi/CdiCamelExtension.java | 146 +++-
 .../java/org/apache/camel/cdi/CdiSpiHelper.java |  95 +++
 .../org/apache/camel/cdi/ImportResource.java    |  29 +
 .../apache/camel/cdi/ListParameterizedType.java |  45 ++
 .../java/org/apache/camel/cdi/NamedLiteral.java |  41 ++
 .../org/apache/camel/cdi/ResourceHelper.java    |  38 +
 .../main/java/org/apache/camel/cdi/Startup.java |  39 +
 .../apache/camel/cdi/SyntheticAnnotated.java    |  82 +++
 .../org/apache/camel/cdi/SyntheticBean.java     | 102 +++
 .../camel/cdi/SyntheticBeanAttributes.java      |  77 ++
 .../camel/cdi/SyntheticInjectionTarget.java     |  81 +++
 .../org/apache/camel/cdi/XmlCdiBeanFactory.java | 464 ++++++++++++
 .../apache/camel/cdi/XmlCdiJaxbContexts.java    |  44 ++
 .../camel/cdi/XmlErrorHandlerFactoryBean.java   | 139 ++++
 .../cdi/XmlFactoryBeanInjectionTarget.java      |  56 ++
 .../apache/camel/cdi/XmlProxyFactoryBean.java   | 103 +++
 .../camel/cdi/XmlServiceExporterBean.java       |  95 +++
 .../cdi/xml/ApplicationContextFactoryBean.java  | 105 +++
 .../apache/camel/cdi/xml/BeanManagerAware.java  |  25 +
 .../apache/camel/cdi/xml/BeanManagerHelper.java |  38 +
 .../camel/cdi/xml/CamelContextFactoryBean.java  | 719 +++++++++++++++++++
 .../cdi/xml/ConsumerTemplateFactoryBean.java    |  53 ++
 .../cdi/xml/ContextScanRouteBuilderFinder.java  |  86 +++
 .../camel/cdi/xml/EndpointFactoryBean.java      |  53 ++
 .../camel/cdi/xml/ErrorHandlerDefinition.java   | 210 ++++++
 .../apache/camel/cdi/xml/ErrorHandlerType.java  |  62 ++
 .../apache/camel/cdi/xml/ImportDefinition.java  |  42 ++
 .../cdi/xml/PackageScanRouteBuilderFinder.java  |  92 +++
 .../cdi/xml/ProducerTemplateFactoryBean.java    |  62 ++
 .../camel/cdi/xml/ProxyFactoryDefinition.java   |  87 +++
 .../cdi/xml/RedeliveryPolicyFactoryBean.java    |  52 ++
 .../camel/cdi/xml/RestContextDefinition.java    |  44 ++
 .../camel/cdi/xml/RouteContextDefinition.java   |  44 ++
 .../cdi/xml/ServiceExporterDefinition.java      |  75 ++
 .../camel/cdi/xml/ThreadPoolFactoryBean.java    |  53 ++
 .../org/apache/camel/cdi/xml/package-info.java  |  25 +
 .../src/main/resources/META-INF/beans.xml       |   7 +
 .../org/apache/camel/cdi/xml/jaxb.index         |  28 +
 .../java/org/apache/camel/cdi/bean/Service.java |  23 +
 .../cdi/mock/DummyRestConsumerFactory.java      |  66 ++
 .../org/apache/camel/cdi/rule/LogEvent.java     |  44 ++
 .../apache/camel/cdi/rule/LogEventMatcher.java  |  98 +++
 .../apache/camel/cdi/rule/LogEventVerifier.java |  39 +
 .../org/apache/camel/cdi/rule/LogVerifier.java  |   6 +-
 .../cdi/test/RouteDefinitionsFromXmlTest.java   |   2 +-
 .../org/apache/camel/cdi/test/XmlBeansTest.java |  76 ++
 .../camel/cdi/test/XmlConsumerTemplateTest.java |  89 +++
 .../apache/camel/cdi/test/XmlEndpointTest.java  | 111 +++
 .../cdi/test/XmlErrorHandlerLoggingTest.java    | 132 ++++
 .../cdi/test/XmlErrorHandlerPolicyTest.java     | 141 ++++
 .../camel/cdi/test/XmlErrorHandlerTest.java     | 105 +++
 .../camel/cdi/test/XmlMultiContextsTest.java    | 142 ++++
 .../camel/cdi/test/XmlProducerTemplateTest.java |  95 +++
 .../cdi/test/XmlPropertyPlaceholderTest.java    |  62 ++
 .../camel/cdi/test/XmlProxyFactoryTest.java     |  70 ++
 .../camel/cdi/test/XmlRestContextTest.java      | 105 +++
 .../cdi/test/XmlRouteContextImportTest.java     | 101 +++
 .../cdi/test/XmlRouteContextResourceTest.java   |  80 +++
 .../camel/cdi/test/XmlRoutesDefinitionTest.java |  74 ++
 .../camel/cdi/test/XmlServiceExporterTest.java  |  81 +++
 .../cdi/test/XmlThreadPoolProfileTest.java      |  81 +++
 .../camel/cdi/test/XmlThreadPoolTest.java       |  77 ++
 .../src/test/resources/camel-context-beans.xml  |  34 +
 .../test/resources/camel-context-consumer.xml   |  27 +
 .../test/resources/camel-context-endpoint.xml   |  30 +
 .../camel-context-errorHandler-logging.xml      |  42 ++
 .../camel-context-errorHandler-policy.xml       |  43 ++
 .../resources/camel-context-errorHandler.xml    |  49 ++
 .../src/test/resources/camel-context-export.xml |  26 +
 .../test/resources/camel-context-multiples.xml  |  37 +
 .../test/resources/camel-context-producer.xml   |  27 +
 .../test/resources/camel-context-properties.xml |  22 +
 .../src/test/resources/camel-context-proxy.xml  |  31 +
 .../resources/camel-context-restContext.xml     |  24 +
 .../resources/camel-context-restContextRef.xml  |  30 +
 .../resources/camel-context-routeContext.xml    |  30 +
 .../camel-context-routeContextRef-import.xml    |  39 +
 .../resources/camel-context-routeContextRef.xml |  40 ++
 .../src/test/resources/camel-context-routes.xml |  23 +
 .../test/resources/camel-context-threadPool.xml |  41 ++
 .../camel-context-threadPoolProfile.xml         |  40 ++
 .../camel-cdi/src/test/resources/routes.xml     |  24 -
 88 files changed, 6179 insertions(+), 305 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-cdi/pom.xml b/components/camel-cdi/pom.xml
index a9ca2fb..f47c765 100644
--- a/components/camel-cdi/pom.xml
+++ b/components/camel-cdi/pom.xml
@@ -89,6 +89,13 @@
 
     <dependency>
       <groupId>org.apache.camel</groupId>
+      <artifactId>camel-core-xml</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.camel</groupId>
       <artifactId>camel-core-osgi</artifactId>
       <version>${project.version}</version>
       <scope>provided</scope>
@@ -266,6 +273,8 @@
                 <exclude>**/UnstoppedCamelContext*Test.java</exclude>
                 <!-- Reactivate when OWB-1122 is fixed -->
                 <exclude>**/ProgrammaticLookupTest.java</exclude>
+                <!-- Reactivate when OWB-1126 is fixed -->
+                <exclude>**/Xml*Test.java</exclude>
               </excludes>
             </configuration>
           </plugin>
@@ -328,6 +337,8 @@
               <excludes>
                 <!-- Reactivate when OWB-1122 is fixed -->
                 <exclude>**/ProgrammaticLookupTest.java</exclude>
+                <!-- Reactivate when OWB-1126 is fixed -->
+                <exclude>**/Xml*Test.java</exclude>
               </excludes>
             </configuration>
           </plugin>

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/ApplicationScopedLiteral.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/ApplicationScopedLiteral.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ApplicationScopedLiteral.java
new file mode 100755
index 0000000..185c1a4
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ApplicationScopedLiteral.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.util.AnnotationLiteral;
+
+@Vetoed
+final class ApplicationScopedLiteral extends AnnotationLiteral<ApplicationScoped> implements ApplicationScoped {
+
+    static final ApplicationScoped APPLICATION_SCOPED = new ApplicationScopedLiteral();
+
+    private static final long serialVersionUID = 1L;
+
+    private ApplicationScopedLiteral() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/BeanManagerHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/BeanManagerHelper.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/BeanManagerHelper.java
index 9da35c1..d454270 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/BeanManagerHelper.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/BeanManagerHelper.java
@@ -16,13 +16,14 @@
  */
 package org.apache.camel.cdi;
 
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
 import java.lang.annotation.Annotation;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+
 @Vetoed
 final class BeanManagerHelper {
 

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextDefaultProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextDefaultProducer.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextDefaultProducer.java
deleted file mode 100644
index 6412bc7..0000000
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CamelContextDefaultProducer.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.cdi;
-
-import java.util.Collections;
-import java.util.Set;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.InjectionTarget;
-
-import org.apache.camel.impl.DefaultCamelContext;
-
-@Vetoed
-final class CamelContextDefaultProducer implements InjectionTarget<DefaultCamelContext> {
-
-    @Override
-    public DefaultCamelContext produce(CreationalContext<DefaultCamelContext> ctx) {
-        return new DefaultCamelContext();
-    }
-
-    @Override
-    public void inject(DefaultCamelContext instance, CreationalContext<DefaultCamelContext> ctx) {
-    }
-
-    @Override
-    public void postConstruct(DefaultCamelContext instance) {
-    }
-
-    @Override
-    public void preDestroy(DefaultCamelContext instance) {
-    }
-
-    @Override
-    public void dispose(DefaultCamelContext instance) {
-    }
-
-    @Override
-    public Set<InjectionPoint> getInjectionPoints() {
-        return Collections.emptySet();
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextAnnotated.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextAnnotated.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextAnnotated.java
deleted file mode 100644
index 39d932d..0000000
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextAnnotated.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.cdi;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import javax.enterprise.inject.spi.Annotated;
-import javax.enterprise.inject.spi.BeanManager;
-
-import org.apache.camel.impl.DefaultCamelContext;
-
-final class CdiCamelContextAnnotated implements Annotated {
-
-    private final Set<Type> types;
-
-    private final Set<Annotation> annotations;
-
-    CdiCamelContextAnnotated(BeanManager manager, Annotation... annotations) {
-        this.types = Collections.unmodifiableSet(manager.createAnnotatedType(DefaultCamelContext.class).getTypeClosure());
-        this.annotations = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(annotations)));
-    }
-
-    @Override
-    public Type getBaseType() {
-        return DefaultCamelContext.class;
-    }
-
-    @Override
-    public Set<Type> getTypeClosure() {
-        return types;
-    }
-
-    @Override
-    public <U extends Annotation> U getAnnotation(Class<U> annotationType) {
-        return CdiSpiHelper.getFirstElementOfType(getAnnotations(), annotationType);
-    }
-
-    @Override
-    public Set<Annotation> getAnnotations() {
-        return annotations;
-    }
-
-    @Override
-    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
-        return getAnnotation(annotationType) != null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextBean.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextBean.java
deleted file mode 100644
index 63db497..0000000
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelContextBean.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * 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.cdi;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.Set;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.InjectionPoint;
-import javax.enterprise.inject.spi.InjectionTarget;
-import javax.enterprise.inject.spi.PassivationCapable;
-
-import org.apache.camel.impl.DefaultCamelContext;
-
-final class CdiCamelContextBean implements Bean<DefaultCamelContext>, PassivationCapable {
-
-    private final Set<Annotation> qualifiers;
-
-    private final Set<Type> types;
-
-    private final InjectionTarget<DefaultCamelContext> target;
-
-    private final String name;
-
-    CdiCamelContextBean(CdiCamelContextAnnotated annotated, InjectionTarget<DefaultCamelContext> target) {
-        this.qualifiers = annotated.getAnnotations();
-        this.types = annotated.getTypeClosure();
-        this.target = target;
-        this.name = annotated.isAnnotationPresent(ContextName.class) ? annotated.getAnnotation(ContextName.class).value() : "Default";
-    }
-
-    @Override
-    public Class<? extends Annotation> getScope() {
-        return ApplicationScoped.class;
-    }
-
-    @Override
-    public Set<Annotation> getQualifiers() {
-        return qualifiers;
-    }
-
-    @Override
-    public DefaultCamelContext create(CreationalContext<DefaultCamelContext> creational) {
-        DefaultCamelContext context = target.produce(creational);
-        target.inject(context, creational);
-        target.postConstruct(context);
-        creational.push(context);
-        return context;
-    }
-
-    @Override
-    public void destroy(DefaultCamelContext instance, CreationalContext<DefaultCamelContext> creational) {
-        target.preDestroy(instance);
-        target.dispose(instance);
-        creational.release();
-    }
-
-    @Override
-    public Class<DefaultCamelContext> getBeanClass() {
-        return DefaultCamelContext.class;
-    }
-
-    @Override
-    public Set<InjectionPoint> getInjectionPoints() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public String getName() {
-        // Not called as this is not a named bean
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        return "Camel context bean [" + name + "]";
-    }
-
-    @Override
-    public Set<Class<? extends Annotation>> getStereotypes() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public Set<Type> getTypes() {
-        return types;
-    }
-
-    @Override
-    public boolean isAlternative() {
-        return false;
-    }
-
-    @Override
-    public boolean isNullable() {
-        return false;
-    }
-
-    @Override
-    public String getId() {
-        return getClass().getName() + "[" + name + "]";
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
index ea4a0c1..69a205b 100755
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiCamelExtension.java
@@ -28,6 +28,8 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
 import static java.util.Collections.newSetFromMap;
 import javax.enterprise.event.Observes;
 import javax.enterprise.inject.Default;
@@ -64,15 +66,23 @@ import org.apache.camel.ProducerTemplate;
 import org.apache.camel.PropertyInject;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.ServiceStatus;
+import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.management.event.AbstractExchangeEvent;
 import org.apache.camel.model.RouteContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.cdi.AnyLiteral.ANY;
+import static org.apache.camel.cdi.ApplicationScopedLiteral.APPLICATION_SCOPED;
+import static org.apache.camel.cdi.BeanManagerHelper.getReference;
+import static org.apache.camel.cdi.BeanManagerHelper.getReferencesByType;
+import static org.apache.camel.cdi.CdiSpiHelper.excludeElementOfTypes;
+import static org.apache.camel.cdi.CdiSpiHelper.getQualifiers;
+import static org.apache.camel.cdi.CdiSpiHelper.getRawType;
 import static org.apache.camel.cdi.CdiSpiHelper.hasAnnotation;
 import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
 import static org.apache.camel.cdi.Excluded.EXCLUDED;
+import static org.apache.camel.cdi.Startup.Literal.STARTUP;
 
 public class CdiCamelExtension implements Extension {
 
@@ -88,6 +98,8 @@ public class CdiCamelExtension implements Extension {
 
     private final Map<InjectionPoint, ForwardingObserverMethod<?>> cdiEventEndpoints = new ConcurrentHashMap<>();
 
+    private final Set<Bean<?>> contextBeans = newSetFromMap(new ConcurrentHashMap<Bean<?>, Boolean>());
+
     private final Set<Annotation> contextQualifiers = newSetFromMap(new ConcurrentHashMap<Annotation, Boolean>());
 
     private final Set<Annotation> eventQualifiers = newSetFromMap(new ConcurrentHashMap<Annotation, Boolean>());
@@ -98,6 +110,8 @@ public class CdiCamelExtension implements Extension {
 
     private final Set<ContextName> contextNames = newSetFromMap(new ConcurrentHashMap<ContextName, Boolean>());
 
+    private final Set<ImportResource> resources = newSetFromMap(new ConcurrentHashMap<>());
+
     ForwardingObserverMethod<?> getObserverMethod(InjectionPoint ip) {
         return cdiEventEndpoints.get(ip);
     }
@@ -123,6 +137,9 @@ public class CdiCamelExtension implements Extension {
         if (hasAnnotation(pat.getAnnotatedType(), Consume.class)) {
             eagerBeans.add(pat.getAnnotatedType());
         }
+        if (hasAnnotation(pat.getAnnotatedType(), ImportResource.class)) {
+            resources.add(pat.getAnnotatedType().getAnnotation(ImportResource.class));
+        }
     }
 
     private void camelContextAware(@Observes ProcessAnnotatedType<? extends CamelContextAware> pat) {
@@ -145,7 +162,7 @@ public class CdiCamelExtension implements Extension {
 
     private void cdiEventEndpoints(@Observes ProcessBean<?> pb) {
         for (InjectionPoint ip : pb.getBean().getInjectionPoints()) {
-            if (!CdiEventEndpoint.class.equals(CdiSpiHelper.getRawType(ip.getType()))) {
+            if (!CdiEventEndpoint.class.equals(getRawType(ip.getType()))) {
                 continue;
             }
             // TODO: refine the key to the type and qualifiers instead of the whole injection point as it leads to registering redundant observers
@@ -176,11 +193,11 @@ public class CdiCamelExtension implements Extension {
             if (!am.isAnnotationPresent(Produces.class)) {
                 continue;
             }
-            Class<?> type = CdiSpiHelper.getRawType(am.getBaseType());
+            Class<?> type = getRawType(am.getBaseType());
             if (Endpoint.class.isAssignableFrom(type)
                 || ConsumerTemplate.class.equals(type)
                 || ProducerTemplate.class.equals(type)) {
-                Set<Annotation> qualifiers = CdiSpiHelper.getQualifiers(am, manager);
+                Set<Annotation> qualifiers = getQualifiers(am, manager);
                 producerQualifiers.put(am.getJavaMember(), qualifiers);
                 Set<Annotation> annotations = new HashSet<>(am.getAnnotations());
                 annotations.removeAll(qualifiers);
@@ -207,35 +224,80 @@ public class CdiCamelExtension implements Extension {
     }
 
     private <T extends CamelContext> void camelContextBeans(@Observes ProcessBean<T> pb) {
-        contextQualifiers.addAll(pb.getBean().getQualifiers());
+        contextBeans.add(pb.getBean());
     }
 
     private <T extends CamelContext> void camelContextProducerFields(@Observes ProcessProducerField<T, ?> pb) {
-        contextQualifiers.addAll(pb.getBean().getQualifiers());
+        contextBeans.add(pb.getBean());
     }
 
     private <T extends CamelContext> void camelContextProducerMethods(@Observes ProcessProducerMethod<T, ?> pb) {
-        contextQualifiers.addAll(pb.getBean().getQualifiers());
+        contextBeans.add(pb.getBean());
     }
 
     private void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager manager) {
-        // Missing @ContextName Camel context qualifiers
-        contextNames.removeAll(contextQualifiers);
-        if (contextQualifiers.isEmpty() && contextNames.isEmpty()) {
-            // Add a @Default Camel context bean if any
-            abd.addBean(camelContextBean(manager, ANY, DEFAULT));
-        } else if (contextQualifiers.isEmpty() && contextNames.size() == 1) {
-            // Add a @ContextName and @Default Camel context bean if only one
-            abd.addBean(camelContextBean(manager, ANY, DEFAULT, contextNames.iterator().next()));
-        } else {
-            // Add missing @ContextName Camel context beans
-            for (ContextName name : contextNames) {
-                abd.addBean(camelContextBean(manager, ANY, name));
+        // The set of programmatic beans to be added
+        Set<SyntheticBean<?>> beans = new HashSet<>();
+
+        // Add beans from Camel XML resources
+        for (ImportResource resource : resources) {
+            XmlCdiBeanFactory factory = XmlCdiBeanFactory.with(manager, environment, this);
+            for (String path : resource.value()) {
+                try {
+                    beans.addAll(factory.beansFrom(path));
+                } catch (NoClassDefFoundError cause) {
+                    if (cause.getMessage().contains("AbstractCamelContextFactoryBean")) {
+                        logger.error("Importing Camel XML requires to have the 'camel-core-xml' dependency in the classpath!");
+                    }
+                    throw cause;
+                } catch (Exception cause) {
+                    abd.addDefinitionError(
+                        new InjectionException(
+                            "Error while importing resource [" + ResourceHelper.getResource(path) + "]", cause));
+                }
+            }
+        }
+
+        // The set of all the Camel context beans
+        Set<Bean<?>> contexts = new HashSet<>();
+
+        // From the discovered annotated types
+        contextBeans.stream()
+            .peek(contexts::add)
+            .map(Bean::getQualifiers)
+            .forEach(contextQualifiers::addAll);
+
+        // From the imported Camel XML
+        beans.stream()
+            .filter(bean -> bean.getTypes().contains(CamelContext.class))
+            .peek(contexts::add)
+            .map(Bean::getQualifiers)
+            .forEach(contextQualifiers::addAll);
+
+        // From the @ContextName qualifiers on RoutesBuilder beans
+        contextNames.stream()
+            .filter(name -> !contextQualifiers.contains(name))
+            .peek(contextQualifiers::add)
+            .map(name -> camelContextBean(manager, ANY, name, APPLICATION_SCOPED))
+            .peek(contexts::add)
+            .forEach(beans::add);
+
+        if (contexts.size() == 0) {
+            // Add @Default Camel context bean if any
+            beans.add(camelContextBean(manager, ANY, DEFAULT, APPLICATION_SCOPED));
+        } else if (contexts.size() == 1) {
+            // Add the @Default qualifier if there is only one Camel context bean
+            Bean<?> context = contexts.iterator().next();
+            if (!context.getQualifiers().contains(DEFAULT)) {
+                // Only decorate if that's a programmatic bean
+                if (context instanceof SyntheticBean) {
+                    ((SyntheticBean<?>) context).addQualifier(DEFAULT);
+                }
             }
         }
 
-        // Update @ContextName Camel context qualifiers
-        contextQualifiers.addAll(contextNames);
+        // Finally add the beans to the deployment
+        beans.forEach(abd::addBean);
 
         // Then update the Camel producer beans
         for (Map.Entry<Method, Bean<?>> producer : producerBeans.entrySet()) {
@@ -250,7 +312,7 @@ public class CdiCamelExtension implements Extension {
                 if (Endpoint.class.isAssignableFrom(type)
                     || ConsumerTemplate.class.equals(type)
                     || ProducerTemplate.class.equals(type)) {
-                    qualifiers.addAll(CdiSpiHelper.excludeElementOfTypes(contextQualifiers, Default.class, Named.class));
+                    qualifiers.addAll(excludeElementOfTypes(contextQualifiers, Default.class, Named.class));
                 }
             }
             // TODO: would be more correct to add a bean for each Camel context bean
@@ -263,15 +325,19 @@ public class CdiCamelExtension implements Extension {
         }
     }
 
-    private Bean<?> camelContextBean(BeanManager manager, Annotation... qualifiers) {
-        CdiCamelContextAnnotated annotated = new CdiCamelContextAnnotated(manager, qualifiers);
-        return new CdiCamelContextBean(annotated, environment.camelContextInjectionTarget(new CamelContextDefaultProducer(), annotated, manager, this));
+    private SyntheticBean<?> camelContextBean(BeanManager manager, Annotation... qualifiers) {
+        SyntheticAnnotated annotated = new SyntheticAnnotated(DefaultCamelContext.class,
+            manager.createAnnotatedType(DefaultCamelContext.class).getTypeClosure(), qualifiers);
+        return new SyntheticBean<>(manager, annotated, DefaultCamelContext.class,
+            environment.camelContextInjectionTarget(
+                new SyntheticInjectionTarget<>(DefaultCamelContext::new), annotated, manager, this), bean ->
+            "Default Camel context bean with qualifiers " + bean.getQualifiers());
     }
 
     private void afterDeploymentValidation(@Observes AfterDeploymentValidation adv, BeanManager manager) {
         Collection<CamelContext> contexts = new ArrayList<>();
         for (Bean<?> context : manager.getBeans(CamelContext.class, ANY)) {
-            contexts.add(BeanManagerHelper.getReference(manager, CamelContext.class, context));
+            contexts.add(getReference(manager, CamelContext.class, context));
         }
 
         // Add type converters to Camel contexts
@@ -300,11 +366,16 @@ public class CdiCamelExtension implements Extension {
             return;
         }
 
-        // Trigger eager beans instantiation
+        // Trigger eager beans instantiation (calling toString is necessary to force
+        // the initialization of normal-scoped beans).
+        // FIXME: This does not work with OpenWebBeans for bean whose bean type is an
+        // interface as the Object methods does not get forwarded to the bean instances!
         for (AnnotatedType<?> type : eagerBeans) {
             // Calling toString is necessary to force the initialization of normal-scoped beans
-            BeanManagerHelper.getReferencesByType(manager, type.getJavaClass(), ANY).toString();
+            getReferencesByType(manager, type.getJavaClass(), ANY).toString();
         }
+        manager.getBeans(Object.class, ANY, STARTUP).stream()
+            .forEach(bean -> getReference(manager, bean.getBeanClass(), bean).toString());
 
         // Start Camel contexts
         for (CamelContext context : contexts) {
@@ -320,29 +391,30 @@ public class CdiCamelExtension implements Extension {
         }
 
         // Clean-up
-        converters.clear();
-        camelBeans.clear();
-        eagerBeans.clear();
-        producerBeans.clear();
-        producerQualifiers.clear();
-        contextNames.clear();
+        Stream.of(converters, camelBeans, eagerBeans, contextBeans, contextNames).forEach(Set::clear);
+        Stream.of(producerBeans, producerQualifiers).forEach(Map::clear);
     }
 
     private boolean addRouteToContext(Bean<?> routeBean, Bean<?> contextBean, BeanManager manager, AfterDeploymentValidation adv) {
         try {
-            CamelContext context = BeanManagerHelper.getReference(manager, CamelContext.class, contextBean);
+            CamelContext context = getReference(manager, CamelContext.class, contextBean);
             try {
-                Object route = BeanManagerHelper.getReference(manager, Object.class, routeBean);
+                Object route = getReference(manager, Object.class, routeBean);
                 if (route instanceof RoutesBuilder) {
                     context.addRoutes((RoutesBuilder) route);
                 } else if (route instanceof RouteContainer) {
                     context.addRouteDefinitions(((RouteContainer) route).getRoutes());
                 } else {
-                    throw new IllegalArgumentException("Invalid routes type [" + routeBean.getBeanClass().getName() + "], must be either of type RoutesBuilder or RouteContainer!");
+                    throw new IllegalArgumentException(
+                        "Invalid routes type [" + routeBean.getBeanClass().getName() + "], "
+                            + "must be either of type RoutesBuilder or RouteContainer!");
                 }
                 return true;
             } catch (Exception cause) {
-                adv.addDeploymentProblem(new InjectionException("Error adding routes of type [" + routeBean.getBeanClass().getName() + "] to Camel context [" + context.getName() + "]", cause));
+                adv.addDeploymentProblem(
+                    new InjectionException(
+                        "Error adding routes of type [" + routeBean.getBeanClass().getName() + "] "
+                            + "to Camel context [" + context.getName() + "]", cause));
             }
         } catch (Exception exception) {
             adv.addDeploymentProblem(exception);

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
index e1e6f62..341fefa 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/CdiSpiHelper.java
@@ -19,18 +19,26 @@ package org.apache.camel.cdi;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Array;
 import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import java.lang.reflect.WildcardType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.AnnotatedConstructor;
 import javax.enterprise.inject.spi.AnnotatedField;
 import javax.enterprise.inject.spi.AnnotatedMethod;
 import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.InjectionPoint;
 
@@ -147,4 +155,91 @@ final class CdiSpiHelper {
         qualifiers.add(ANY);
         return qualifiers;
     }
+
+    /**
+     * Generates a unique signature for {@link Bean}.
+     */
+    static String createBeanId(Bean<?> bean) {
+        return Stream.of(bean.getName(),
+            bean.getScope().getName(),
+            createAnnotationCollectionId(bean.getQualifiers()),
+            createTypeCollectionId(bean.getTypes()))
+            .filter(s -> s != null)
+            .collect(Collectors.joining(","));
+    }
+
+    /**
+     * Generates a unique signature of a collection of types.
+     */
+    private static String createTypeCollectionId(Collection<? extends Type> types) {
+        return types.stream()
+            .sorted((t1, t2) -> createTypeId(t1).compareTo(createTypeId(t2)))
+            .map(CdiSpiHelper::createTypeId)
+            .collect(Collectors.joining(",", "[", "]"));
+    }
+
+    /**
+     * Generates a unique signature for a {@link Type}.
+     */
+    private static String createTypeId(Type type) {
+        if (type instanceof Class<?>) {
+            return Class.class.cast(type).getName();
+        }
+
+        if (type instanceof ParameterizedType) {
+            return createTypeId(((ParameterizedType) type).getRawType())
+                + Stream.of(((ParameterizedType) type).getActualTypeArguments())
+                .map(CdiSpiHelper::createTypeId)
+                .collect(Collectors.joining(",", "<", ">"));
+        }
+
+        if (type instanceof TypeVariable<?>) {
+            return TypeVariable.class.cast(type).getName();
+        }
+
+        if (type instanceof GenericArrayType) {
+            return createTypeId(GenericArrayType.class.cast(type).getGenericComponentType());
+        }
+
+        throw new UnsupportedOperationException("Unable to create type id for type [" + type + "]");
+    }
+
+    /**
+     * Generates a unique signature for a collection of annotations.
+     */
+    private static String createAnnotationCollectionId(Collection<Annotation> annotations) {
+        if (annotations.isEmpty()) {
+            return "";
+        }
+
+        return annotations.stream()
+            .sorted((a1, a2) -> a1.annotationType().getName().compareTo(a2.annotationType().getName()))
+            .map(CdiSpiHelper::createAnnotationId)
+            .collect(Collectors.joining(",", "[", "]"));
+    }
+
+    /**
+     * Generates a unique signature for an {@link Annotation}.
+     */
+    private static String createAnnotationId(Annotation annotation) {
+        Method[] methods = AccessController.doPrivileged(
+            (PrivilegedAction<Method[]>) () -> annotation.annotationType().getDeclaredMethods());
+
+        return Stream.of(methods)
+            .sorted((m1, m2) -> m1.getName().compareTo(m2.getName()))
+            .collect(() -> new StringJoiner(",", "@(", ")"),
+                (joiner, method) -> {
+                    try {
+                        joiner
+                            .add(method.getName()).add("=")
+                            .add(method.invoke(annotation).toString());
+                    } catch (NullPointerException | IllegalArgumentException | IllegalAccessException | InvocationTargetException cause) {
+                        throw new RuntimeException(
+                            "Error while accessing member [" + method.getName() + "]"
+                                + " of annotation [" + annotation.annotationType().getName() + "]", cause);
+                    }
+                },
+                StringJoiner::merge)
+            .toString();
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/ImportResource.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/ImportResource.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ImportResource.java
new file mode 100644
index 0000000..b21c757
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ImportResource.java
@@ -0,0 +1,29 @@
+/**
+ * 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.cdi;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface ImportResource {
+
+    String[] value() default {};
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/ListParameterizedType.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/ListParameterizedType.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ListParameterizedType.java
new file mode 100644
index 0000000..e177e47
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ListParameterizedType.java
@@ -0,0 +1,45 @@
+/**
+ * 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.cdi;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+final class ListParameterizedType implements ParameterizedType {
+
+    private final Type argument;
+
+    ListParameterizedType(Type argument) {
+        this.argument = argument;
+    }
+
+    @Override
+    public Type[] getActualTypeArguments() {
+        return new Type[]{argument};
+    }
+
+    @Override
+    public Type getRawType() {
+        return List.class;
+    }
+
+    @Override
+    public Type getOwnerType() {
+        return null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/NamedLiteral.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/NamedLiteral.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/NamedLiteral.java
new file mode 100755
index 0000000..c8e1a66
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/NamedLiteral.java
@@ -0,0 +1,41 @@
+/**
+ * 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.cdi;
+
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Named;
+
+@Vetoed
+final class NamedLiteral extends AnnotationLiteral<Named> implements Named {
+
+    private static final long serialVersionUID = 1L;
+
+    private final String name;
+
+    private NamedLiteral(String name) {
+        this.name = name;
+    }
+
+    public static Named of(String name) {
+        return new NamedLiteral(name);
+    }
+
+    @Override
+    public String value() {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/ResourceHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/ResourceHelper.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ResourceHelper.java
new file mode 100644
index 0000000..0cfef7e
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/ResourceHelper.java
@@ -0,0 +1,38 @@
+/**
+ * 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.cdi;
+
+import java.net.URL;
+
+@Vetoed
+final class ResourceHelper {
+
+    private ResourceHelper() {
+    }
+
+    static URL getResource(String path) {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = ResourceHelper.class.getClassLoader();
+        }
+        if (loader == null) {
+            loader = ClassLoader.getSystemClassLoader();
+        }
+
+        return loader.getResource(path);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
new file mode 100755
index 0000000..936fdd6
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/Startup.java
@@ -0,0 +1,39 @@
+/**
+ * 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.cdi;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Qualifier;
+
+@Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
+@interface Startup {
+
+    @Vetoed
+    final class Literal extends AnnotationLiteral<Startup> implements Startup {
+
+        static final Startup STARTUP = new Literal();
+
+        private Literal() {
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticAnnotated.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticAnnotated.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticAnnotated.java
new file mode 100644
index 0000000..803e41c
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticAnnotated.java
@@ -0,0 +1,82 @@
+/**
+ * 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.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.inject.spi.Annotated;
+
+@Vetoed
+final class SyntheticAnnotated implements Annotated {
+
+    private final Class<?> type;
+
+    private final Set<Type> types;
+
+    private final Set<Annotation> annotations;
+
+    SyntheticAnnotated(Class<?> type, Set<Type> types, Annotation... annotations) {
+        this(type, types, Arrays.asList(annotations));
+    }
+
+    SyntheticAnnotated(Class<?> type, Set<Type> types, Collection<Annotation> annotations) {
+        this.type = type;
+        this.types = types;
+        this.annotations = new HashSet<>(annotations);
+    }
+
+    <A extends Annotation> void addAnnotation(A annotation) {
+        annotations.add(annotation);
+    }
+
+    @Override
+    public Type getBaseType() {
+        return type;
+    }
+
+    @Override
+    public Set<Type> getTypeClosure() {
+        return Collections.unmodifiableSet(types);
+    }
+
+    @Override
+    public Set<Annotation> getAnnotations() {
+        return Collections.unmodifiableSet(annotations);
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> type) {
+        return annotations.stream()
+            .filter(a -> a.annotationType().equals(type))
+            .findAny()
+            .map(type::cast)
+            .orElse(null);
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> type) {
+        return annotations.stream()
+            .filter(a -> a.annotationType().equals(type))
+            .findAny()
+            .isPresent();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBean.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBean.java
new file mode 100644
index 0000000..bd280f9
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBean.java
@@ -0,0 +1,102 @@
+/**
+ * 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.cdi;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.function.Function;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.CreationException;
+import javax.enterprise.inject.InjectionException;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.PassivationCapable;
+
+import static org.apache.camel.cdi.CdiSpiHelper.createBeanId;
+
+class SyntheticBean<T> extends SyntheticBeanAttributes<T> implements Bean<T>, PassivationCapable {
+
+    private final Class<?> type;
+
+    private final InjectionTarget<T> target;
+
+    private final Function<Bean<T>, String> toString;
+
+    SyntheticBean(BeanManager manager, SyntheticAnnotated annotated, Class<?> type, InjectionTarget<T> target, Function<Bean<T>, String> toString) {
+        super(manager, annotated);
+        this.type = type;
+        this.target = target;
+        this.toString = toString;
+    }
+
+    @Override
+    public Class<?> getBeanClass() {
+        return type;
+    }
+
+    @Override
+    public T create(CreationalContext<T> creationalContext) {
+        try {
+            T instance = target.produce(creationalContext);
+            target.inject(instance, creationalContext);
+            target.postConstruct(instance);
+            return instance;
+        } catch (Exception cause) {
+            throw new CreationException("Error while instantiating " + this, cause);
+        }
+    }
+
+    @Override
+    public void destroy(T instance, CreationalContext<T> creationalContext) {
+        try {
+            target.preDestroy(instance);
+            target.dispose(instance);
+        } catch (Exception cause) {
+            throw new InjectionException("Error while destroying " + this, cause);
+        } finally {
+            creationalContext.release();
+        }
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toString.apply(this);
+    }
+
+    @Override
+    public String getId() {
+        return new StringJoiner("%")
+            .add("CAMEL-CDI")
+            .add(getClass().getSimpleName())
+            .add(type.getName())
+            .add(createBeanId(this))
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBeanAttributes.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBeanAttributes.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBeanAttributes.java
new file mode 100644
index 0000000..f59caf1
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticBeanAttributes.java
@@ -0,0 +1,77 @@
+/**
+ * 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.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Named;
+
+class SyntheticBeanAttributes<T> {
+
+    private final BeanManager manager;
+
+    private final SyntheticAnnotated annotated;
+
+    SyntheticBeanAttributes(BeanManager manager, SyntheticAnnotated annotated) {
+        this.manager = manager;
+        this.annotated = annotated;
+    }
+
+    <A extends Annotation> void addQualifier(A qualifier) {
+        annotated.addAnnotation(qualifier);
+    }
+
+    public Class<? extends Annotation> getScope() {
+        return annotated.getAnnotations().stream()
+            .map(Annotation::annotationType)
+            .filter(manager::isScope)
+            .findAny()
+            .orElse(Dependent.class);
+    }
+
+    public Set<Annotation> getQualifiers() {
+        return annotated.getAnnotations().stream()
+            .filter(a -> manager.isQualifier(a.annotationType()))
+            .collect(Collectors.toSet());
+    }
+
+    public String getName() {
+        return annotated.getAnnotations().stream()
+            .filter(a -> Named.class.equals(a.annotationType()))
+            .map(Named.class::cast)
+            .map(Named::value)
+            .findFirst()
+            .orElse(null);
+    }
+
+    public Set<Class<? extends Annotation>> getStereotypes() {
+        return Collections.emptySet();
+    }
+
+    public Set<Type> getTypes() {
+        return annotated.getTypeClosure();
+    }
+
+    public boolean isAlternative() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticInjectionTarget.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticInjectionTarget.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticInjectionTarget.java
new file mode 100644
index 0000000..76ee6a3
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/SyntheticInjectionTarget.java
@@ -0,0 +1,81 @@
+/**
+ * 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.cdi;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+
+@Vetoed
+class SyntheticInjectionTarget<T> implements InjectionTarget<T> {
+
+    private final Supplier<T> produce;
+
+    private final Consumer<T> postConstruct;
+
+    private final Consumer<T> preDestroy;
+
+    SyntheticInjectionTarget(Supplier<T> produce) {
+        this(produce, t -> {
+        });
+    }
+
+    SyntheticInjectionTarget(Supplier<T> produce, Consumer<T> postConstruct) {
+        this(produce, postConstruct, t -> {
+        });
+    }
+
+    SyntheticInjectionTarget(Supplier<T> produce, Consumer<T> postConstruct, Consumer<T> preDestroy) {
+        this.produce = produce;
+        this.postConstruct = postConstruct;
+        this.preDestroy = preDestroy;
+    }
+
+    @Override
+    public void inject(T instance, CreationalContext<T> ctx) {
+
+    }
+
+    @Override
+    public void postConstruct(T instance) {
+        postConstruct.accept(instance);
+    }
+
+    @Override
+    public void preDestroy(T instance) {
+        preDestroy.accept(instance);
+    }
+
+    @Override
+    public T produce(CreationalContext<T> ctx) {
+        return produce.get();
+    }
+
+    @Override
+    public void dispose(T instance) {
+
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return Collections.emptySet();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
new file mode 100644
index 0000000..9caa6e5
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java
@@ -0,0 +1,464 @@
+/**
+ * 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.cdi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.lang.String.format;
+
+import javax.enterprise.inject.CreationException;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.xml.bind.JAXBException;
+
+import org.apache.camel.cdi.xml.ApplicationContextFactoryBean;
+import org.apache.camel.cdi.xml.BeanManagerAware;
+import org.apache.camel.cdi.xml.CamelContextFactoryBean;
+import org.apache.camel.cdi.xml.ErrorHandlerDefinition;
+import org.apache.camel.cdi.xml.ErrorHandlerType;
+import org.apache.camel.cdi.xml.ImportDefinition;
+import org.apache.camel.cdi.xml.ProxyFactoryDefinition;
+import org.apache.camel.cdi.xml.RestContextDefinition;
+import org.apache.camel.cdi.xml.RouteContextDefinition;
+import org.apache.camel.cdi.xml.ServiceExporterDefinition;
+import org.apache.camel.core.xml.AbstractCamelFactoryBean;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.camel.cdi.AnyLiteral.ANY;
+import static org.apache.camel.cdi.ApplicationScopedLiteral.APPLICATION_SCOPED;
+import static org.apache.camel.cdi.DefaultLiteral.DEFAULT;
+import static org.apache.camel.cdi.Startup.Literal.STARTUP;
+import static org.apache.camel.util.ObjectHelper.isNotEmpty;
+
+final class XmlCdiBeanFactory {
+
+    private final Logger logger = LoggerFactory.getLogger(XmlCdiBeanFactory.class);
+
+    private final BeanManager manager;
+
+    private final CdiCamelEnvironment environment;
+
+    private final CdiCamelExtension extension;
+
+    private XmlCdiBeanFactory(BeanManager manager, CdiCamelEnvironment environment, CdiCamelExtension extension) {
+        this.manager = manager;
+        this.environment = environment;
+        this.extension = extension;
+    }
+
+    static XmlCdiBeanFactory with(BeanManager manager, CdiCamelEnvironment environment, CdiCamelExtension extension) {
+        return new XmlCdiBeanFactory(manager, environment, extension);
+    }
+
+    Set<SyntheticBean<?>> beansFrom(String path) throws JAXBException, IOException {
+        URL url = ResourceHelper.getResource(path);
+        if (url == null) {
+            logger.warn("Unable to locate resource [{}] for import!", path);
+            return Collections.emptySet();
+        }
+        return beansFrom(url);
+    }
+
+    Set<SyntheticBean<?>> beansFrom(URL url) throws JAXBException, IOException {
+        try (InputStream xml = url.openStream()) {
+            Object node = XmlCdiJaxbContexts.CAMEL_CDI.instance()
+                .createUnmarshaller()
+                .unmarshal(xml);
+            if (node instanceof RoutesDefinition) {
+                RoutesDefinition routes = (RoutesDefinition) node;
+                return Collections.singleton(routesDefinitionBean(routes, url));
+            } else if (node instanceof ApplicationContextFactoryBean) {
+                ApplicationContextFactoryBean app = (ApplicationContextFactoryBean) node;
+                Set<SyntheticBean<?>> beans = new HashSet<>();
+                for (CamelContextFactoryBean factory : app.getContexts()) {
+                    SyntheticBean<?> bean = camelContextBean(factory, url);
+                    beans.add(bean);
+                    beans.addAll(camelContextBeans(factory, bean, url));
+                }
+                for (ErrorHandlerDefinition definition : app.getErrorHandlers()) {
+                    beans.add(errorHandlerBean(definition, url));
+                }
+                for (ImportDefinition definition : app.getImports()) {
+                    // Get the base URL as imports are relative to this
+                    String path = url.getFile().substring(0, url.getFile().lastIndexOf('/'));
+                    String base = url.getProtocol() + "://" + url.getHost() + path;
+                    beans.addAll(beansFrom(base + "/" + definition.getResource()));
+                }
+                for (RestContextDefinition factory : app.getRestContexts()) {
+                    beans.add(restContextBean(factory, url));
+                }
+                for (RouteContextDefinition factory : app.getRouteContexts()) {
+                    beans.add(routeContextBean(factory, url));
+                }
+                for (AbstractCamelFactoryBean<?> factory : app.getBeans()) {
+                    if (factory.getId() != null) {
+                        beans.add(camelContextBean(null, factory, url));
+                    }
+                }
+                return beans;
+            } else if (node instanceof CamelContextFactoryBean) {
+                CamelContextFactoryBean factory = (CamelContextFactoryBean) node;
+                Set<SyntheticBean<?>> beans = new HashSet<>();
+                SyntheticBean<?> bean = camelContextBean(factory, url);
+                beans.add(bean);
+                beans.addAll(camelContextBeans(factory, bean, url));
+                return beans;
+            } else if (node instanceof RestContextDefinition) {
+                RestContextDefinition factory = (RestContextDefinition) node;
+                return Collections.singleton(restContextBean(factory, url));
+            } else if (node instanceof RouteContextDefinition) {
+                RouteContextDefinition factory = (RouteContextDefinition) node;
+                return Collections.singleton(routeContextBean(factory, url));
+            }
+        }
+        return Collections.emptySet();
+    }
+
+    private SyntheticBean<?> camelContextBean(CamelContextFactoryBean factory, URL url) {
+        Set<Annotation> annotations = new HashSet<>();
+        annotations.add(ANY);
+        if (factory.getId() != null) {
+            Collections.addAll(annotations,
+                ContextName.Literal.of(factory.getId()), NamedLiteral.of(factory.getId()));
+        } else {
+            annotations.add(DEFAULT);
+            factory.setImplicitId(true);
+            factory.setId(new CdiCamelContextNameStrategy().getNextName());
+        }
+
+        annotations.add(APPLICATION_SCOPED);
+        SyntheticAnnotated annotated = new SyntheticAnnotated(DefaultCamelContext.class,
+            manager.createAnnotatedType(DefaultCamelContext.class).getTypeClosure(),
+            annotations);
+        return new SyntheticBean<>(manager, annotated, DefaultCamelContext.class,
+            environment.camelContextInjectionTarget(
+                new SyntheticInjectionTarget<>(() -> {
+                    DefaultCamelContext context = new DefaultCamelContext();
+                    factory.setContext(context);
+                    factory.setBeanManager(manager);
+                    return context;
+                }, context -> {
+                    try {
+                        factory.afterPropertiesSet();
+                    } catch (Exception cause) {
+                        throw new CreationException(cause);
+                    }
+                }),
+                annotated, manager, extension), bean ->
+                "imported Camel context with "
+                + (factory.isImplicitId() ? "implicit " : "")
+                + "id [" + factory.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers());
+    }
+
+    private Set<SyntheticBean<?>> camelContextBeans(CamelContextFactoryBean factory, Bean<?> context, URL url) {
+        Set<SyntheticBean<?>> beans = new HashSet<>();
+
+        // TODO: WARN log if the definition doesn't have an id
+        if (factory.getBeans() != null) {
+            factory.getBeans().stream()
+                .filter(bean -> bean.getId() != null)
+                .map(bean -> camelContextBean(context, bean, url))
+                .forEach(beans::add);
+        }
+
+        // TODO: define in beans
+        if (factory.getEndpoints() != null) {
+            factory.getEndpoints().stream()
+                .filter(endpoint -> endpoint.getId() != null)
+                .map(endpoint -> camelContextBean(context, endpoint, url))
+                .forEach(beans::add);
+        }
+
+        if (factory.getErrorHandlers() != null) {
+            factory.getErrorHandlers().stream()
+                .filter(handler -> handler.getId() != null)
+                .map(handler -> errorHandlerBean(handler, url))
+                .forEach(beans::add);
+        }
+
+        if (factory.getExports() != null) {
+            factory.getExports().stream()
+                .map(export -> serviceExporterBean(context, export, url))
+                .forEach(beans::add);
+        }
+
+        if (factory.getProxies() != null) {
+            factory.getProxies().stream()
+                .filter(proxy -> proxy.getId() != null)
+                .map(proxy -> proxyFactoryBean(context, proxy, url))
+                .forEach(beans::add);
+        }
+
+        // TODO: define in beans
+        if (factory.getRedeliveryPolicies() != null) {
+            factory.getRedeliveryPolicies().stream()
+                .filter(policy -> policy.getId() != null)
+                .map(policy -> camelContextBean(context, policy, url))
+                .forEach(beans::add);
+        }
+
+        return beans;
+    }
+
+    private SyntheticBean<?> camelContextBean(Bean<?> context, AbstractCamelFactoryBean<?> factory, URL url) {
+        if (factory instanceof BeanManagerAware) {
+            ((BeanManagerAware) factory).setBeanManager(manager);
+        }
+
+        Set<Annotation> annotations = new HashSet<>();
+        annotations.add(ANY);
+        // FIXME: should add @ContextName if the Camel context bean has it
+        annotations.add(factory.getId() != null ? NamedLiteral.of(factory.getId()) : DEFAULT);
+
+        // TODO: should that be @Singleton to enable injection points with bean instance type?
+        if (factory.isSingleton()) {
+            annotations.add(APPLICATION_SCOPED);
+        }
+
+        return new SyntheticBean<>(manager,
+            new SyntheticAnnotated(factory.getObjectType(),
+                manager.createAnnotatedType(factory.getObjectType()).getTypeClosure(),
+                annotations),
+            factory.getObjectType(),
+            new XmlFactoryBeanInjectionTarget<>(manager, factory, context), bean ->
+                "imported bean [" + factory.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers());
+    }
+
+    private SyntheticBean<?> proxyFactoryBean(Bean<?> context, ProxyFactoryDefinition proxy, URL url) {
+        if (ObjectHelper.isEmpty(proxy.getServiceRef()) && ObjectHelper.isEmpty(proxy.getServiceUrl())) {
+            throw new CreationException(
+                format("Missing [%s] or [%s] attribute for imported bean [%s] from resource [%s]",
+                    "serviceRef", "serviceUrl", proxy.getId(), url));
+        }
+
+        return new XmlProxyFactoryBean<>(manager,
+            new SyntheticAnnotated(proxy.getServiceInterface(),
+                manager.createAnnotatedType(proxy.getServiceInterface()).getTypeClosure(),
+                APPLICATION_SCOPED, ANY, NamedLiteral.of(proxy.getId())),
+            proxy.getServiceInterface(), bean ->
+                "imported bean [" + proxy.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers(),
+            context, proxy);
+    }
+
+    private SyntheticBean<?> serviceExporterBean(Bean<?> context, ServiceExporterDefinition exporter, URL url) {
+        // TODO: replace with CreationException
+        Objects.requireNonNull(exporter.getServiceRef(),
+            () -> format("Missing [%s] attribute for imported bean [%s] from resource [%s]",
+                "serviceRef", Objects.toString(exporter.getId(), "export"), url));
+
+        Class<?> type;
+        if (exporter.getServiceInterface() != null) {
+            type = exporter.getServiceInterface();
+        } else {
+            Bean<?> bean = manager.resolve(manager.getBeans(exporter.getServiceRef()));
+            if (bean != null) {
+                type = bean.getBeanClass();
+            } else {
+                Objects.requireNonNull(exporter.getServiceInterface(),
+                    () -> format("Missing [%s] attribute for imported bean [%s] from resource [%s]",
+                        "serviceInterface", Objects.toString(exporter.getId(), "export"), url));
+                type = exporter.getServiceInterface();
+            }
+        }
+
+        Set<Type> types = new HashSet<>(manager.createAnnotatedType(type).getTypeClosure());
+        // Weld does not add Object.class for interfaces as they do not extend Object.class.
+        // Though let's add it so that it's possible to lookup by bean type Object.class
+        // beans whose bean class is an interface (for startup beans).
+        types.add(Object.class);
+
+        return new XmlServiceExporterBean<>(manager,
+            new SyntheticAnnotated(type, types, APPLICATION_SCOPED, ANY, STARTUP,
+                exporter.getId() != null ? NamedLiteral.of(exporter.getId()) : DEFAULT),
+            type, bean ->
+                "imported bean [" + Objects.toString(exporter.getId(), "export") + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers(),
+            context, exporter);
+    }
+
+    private SyntheticBean<?> restContextBean(RestContextDefinition definition, URL url) {
+        Objects.requireNonNull(definition.getId(),
+            () -> format("Missing [%s] attribute for imported bean [%s] from resource [%s]",
+                "id", "restContext", url));
+
+        return new SyntheticBean<>(manager,
+            new SyntheticAnnotated(List.class,
+                Stream.of(List.class, new ListParameterizedType(RestDefinition.class))
+                    .collect(Collectors.toSet()),
+                ANY, NamedLiteral.of(definition.getId())),
+            List.class,
+            new SyntheticInjectionTarget<>(definition::getRests), bean ->
+                "imported rest context with "
+                + "id [" + definition.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers());
+    }
+
+    private SyntheticBean<?> routeContextBean(RouteContextDefinition definition, URL url) {
+        Objects.requireNonNull(definition.getId(),
+            () -> format("Missing [%s] attribute for imported bean [%s] from resource [%s]",
+                "id", "routeContext", url));
+
+        return new SyntheticBean<>(manager,
+            new SyntheticAnnotated(List.class,
+                Stream.of(List.class, new ListParameterizedType(RouteDefinition.class))
+                    .collect(Collectors.toSet()),
+                ANY, NamedLiteral.of(definition.getId())),
+            List.class,
+            new SyntheticInjectionTarget<>(definition::getRoutes), bean ->
+                "imported route context with "
+                + "id [" + definition.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers());
+    }
+
+    private SyntheticBean<?> routesDefinitionBean(RoutesDefinition definition, URL url) {
+        return new SyntheticBean<>(manager,
+            // TODO: should be @Named if the id is set
+            new SyntheticAnnotated(RoutesDefinition.class,
+                manager.createAnnotatedType(RoutesDefinition.class).getTypeClosure(),
+                ANY, DEFAULT),
+            RoutesDefinition.class,
+            new SyntheticInjectionTarget<>(() -> definition), bean ->
+                "imported routes definition "
+                + (definition.getId() != null ? "[" + definition.getId() + "] " : "")
+                + "from resource [" + url + "]");
+    }
+
+    private SyntheticBean<?> errorHandlerBean(ErrorHandlerDefinition definition, URL url) {
+        ErrorHandlerType type = definition.getType();
+
+        // Validate attributes according to type
+        if (isNotEmpty(definition.getDeadLetterUri())
+            && !type.equals(ErrorHandlerType.DeadLetterChannel)) {
+            throw attributeNotSupported("deadLetterUri", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getDeadLetterHandleNewException())
+            && !type.equals(ErrorHandlerType.DeadLetterChannel)) {
+            throw attributeNotSupported("deadLetterHandleNewException", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getTransactionTemplateRef())
+            && !type.equals(ErrorHandlerType.TransactionErrorHandler)) {
+            throw attributeNotSupported("transactionTemplateRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getTransactionManagerRef())
+            && !type.equals(ErrorHandlerType.TransactionErrorHandler)) {
+            throw attributeNotSupported("transactionManagerRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getRollbackLoggingLevel())
+            && (!type.equals(ErrorHandlerType.TransactionErrorHandler))) {
+            throw attributeNotSupported("rollbackLoggingLevel", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getUseOriginalMessage())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("useOriginalMessage", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getOnRedeliveryRef())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("onRedeliveryRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getOnExceptionOccurredRef())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("onExceptionOccurredRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getOnPrepareFailureRef())
+            && (type.equals(ErrorHandlerType.TransactionErrorHandler)
+            || type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("onPrepareFailureRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getRetryWhileRef())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("retryWhileRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getOnRedeliveryRef())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("redeliveryPolicyRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getExecutorServiceRef())
+            && (type.equals(ErrorHandlerType.LoggingErrorHandler)
+            || type.equals(ErrorHandlerType.NoErrorHandler))) {
+            throw attributeNotSupported("executorServiceRef", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getLogName())
+            && (!type.equals(ErrorHandlerType.LoggingErrorHandler))) {
+            throw attributeNotSupported("logName", type, definition.getId());
+        }
+
+        if (isNotEmpty(definition.getLevel())
+            && (!type.equals(ErrorHandlerType.LoggingErrorHandler))) {
+            throw attributeNotSupported("level", type, definition.getId());
+        }
+
+        return new XmlErrorHandlerFactoryBean(manager,
+            new SyntheticAnnotated(type.getTypeAsClass(),
+                manager.createAnnotatedType(type.getTypeAsClass()).getTypeClosure(),
+                ANY, NamedLiteral.of(definition.getId())),
+            type.getTypeAsClass(), bean -> "imported error handler with "
+                + "id [" + definition.getId() + "] "
+                + "from resource [" + url + "] "
+                + "with qualifiers " + bean.getQualifiers(),
+            definition);
+    }
+
+    private static CreationException attributeNotSupported(String attribute, ErrorHandlerType type, String id) {
+        return new CreationException(
+            format("Attribute [%s] is not supported by error handler type [%s], in error handler with id [%s]",
+                attribute, type, id));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ba1172ad/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiJaxbContexts.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiJaxbContexts.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiJaxbContexts.java
new file mode 100644
index 0000000..7803324
--- /dev/null
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiJaxbContexts.java
@@ -0,0 +1,44 @@
+/**
+ * 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.cdi;
+
+import java.util.Arrays;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+
+import org.apache.camel.cdi.xml.ApplicationContextFactoryBean;
+import org.apache.camel.model.Constants;
+
+enum XmlCdiJaxbContexts {
+
+    CAMEL_CDI(Constants.JAXB_CONTEXT_PACKAGES, ApplicationContextFactoryBean.class.getPackage().getName());
+
+    private final JAXBContext context;
+
+    XmlCdiJaxbContexts(String... packages) {
+        try {
+            context = JAXBContext.newInstance(String.join(":", packages));
+        } catch (JAXBException cause) {
+            throw new IllegalStateException("Error while creating JAXB context for packages " + Arrays.toString(packages), cause);
+        }
+    }
+
+    JAXBContext instance() {
+        return context;
+    }
+}