You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/10/26 12:47:41 UTC
[camel] branch main updated: Primary spring (#11842)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new f275b466ced Primary spring (#11842)
f275b466ced is described below
commit f275b466ced60c3863139988f84a2dbe2a6ec39b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 26 14:47:34 2023 +0200
Primary spring (#11842)
* CAMEL-20042: camel-spring - findSingleByType should favour @Primary beans from Spring
* Bump threshold for test
* CAMEL-20042: camel-spring - Autowire @Primary beans supported
* CAMEL-20042: camel-spring - Autowire @Primary beans supported
* CAMEL-20042: camel-sql - Stored component should use autowired datasource like sql do.
* CAMEL-20042: camel-spring - Autowire @Primary beans supported
* CAMEL-20042: camel-spring - Autowire @Primary beans supported
---
.../camel/catalog/components/sql-stored.json | 2 +-
.../TransactedStackSizeBreakOnExceptionTest.java | 2 +-
.../org/apache/camel/spring/primary/Customer.java | 23 ++++++
.../apache/camel/spring/primary/CustomerImpl.java | 31 ++++++++
.../camel/spring/primary/FindSingleByTypeTest.java | 90 ++++++++++++++++++++++
.../org/apache/camel/spring/primary/MyService.java | 36 +++++++++
.../apache/camel/spring/primary/findBySingle.xml | 38 +++++++++
.../spi/ApplicationContextBeanRepository.java | 13 ++++
.../sql/stored/SqlStoredComponentConfigurer.java | 5 ++
.../camel/component/sql/stored/sql-stored.json | 2 +-
.../component/sql/stored/SqlStoredComponent.java | 45 ++++-------
.../component/sql/stored/SqlStoredEndpoint.java | 4 +
.../java/org/apache/camel/spi/BeanRepository.java | 9 +--
.../org/apache/camel/support/DefaultRegistry.java | 26 +++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_2.adoc | 15 +++-
15 files changed, 304 insertions(+), 37 deletions(-)
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
index 109ff9de0e7..db619b0c73b 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json
@@ -22,7 +22,7 @@
"lenientProperties": false
},
"componentProperties": {
- "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the DataSource to use to communicate with the database." },
+ "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": true, "secret": false, "description": "Sets the DataSource to use to communicate with the database." },
"lazyStartProducer": { "index": 1, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
"autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
},
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/interceptor/TransactedStackSizeBreakOnExceptionTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/interceptor/TransactedStackSizeBreakOnExceptionTest.java
index b1a6de28a69..11149462fd3 100644
--- a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/interceptor/TransactedStackSizeBreakOnExceptionTest.java
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/interceptor/TransactedStackSizeBreakOnExceptionTest.java
@@ -27,7 +27,7 @@ public class TransactedStackSizeBreakOnExceptionTest extends TransactionClientDa
private static final boolean PRINT_STACK_TRACE = false;
private int total = 100;
- private int failAt = 75;
+ private int failAt = 80;
@Test
public void testStackSize() throws Exception {
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/Customer.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/Customer.java
new file mode 100644
index 00000000000..283f848bbbd
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/Customer.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.primary;
+
+public interface Customer {
+
+ String name();
+
+}
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/CustomerImpl.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/CustomerImpl.java
new file mode 100644
index 00000000000..bbe788beb8c
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/CustomerImpl.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.spring.primary;
+
+public class CustomerImpl implements Customer {
+
+ private final String name;
+
+ public CustomerImpl(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String name() {
+ return name;
+ }
+}
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/FindSingleByTypeTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/FindSingleByTypeTest.java
new file mode 100644
index 00000000000..e570c05bd7a
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/FindSingleByTypeTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.primary;
+
+import java.util.Set;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.NoSuchBeanTypeException;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.spi.UuidGenerator;
+import org.apache.camel.util.IOHelper;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class FindSingleByTypeTest extends ContextTestSupport {
+
+ private AbstractApplicationContext applicationContext;
+
+ @Override
+ @BeforeEach
+ public void setUp() throws Exception {
+ super.setUp();
+ if (context != null) {
+ context.stop();
+ }
+ applicationContext = new ClassPathXmlApplicationContext("org/apache/camel/spring/primary/findBySingle.xml");
+ context = applicationContext.getBean("myCamel", ModelCamelContext.class);
+ }
+
+ @Override
+ @AfterEach
+ public void tearDown() throws Exception {
+ // we're done so let's properly close the application context
+ IOHelper.close(applicationContext);
+
+ super.tearDown();
+ }
+
+ @Test
+ public void testFindSingle() {
+ // should find primary
+ Customer c = context.getRegistry().findSingleByType(Customer.class);
+
+ Assertions.assertNotNull(c);
+ Assertions.assertEquals("Donald", c.name());
+
+ // should not find anything
+ Object o = context.getRegistry().findSingleByType(UuidGenerator.class);
+ Assertions.assertNull(o);
+ }
+
+ @Test
+ public void testFindByType() {
+ // should find primary
+ Set<Customer> set = context.getRegistry().findByType(Customer.class);
+
+ // should find both beans
+ Assertions.assertEquals(2, set.size());
+ }
+
+ @Test
+ public void testFindSingleMandatory() {
+ // should find primary
+ Customer c = context.getRegistry().mandatoryFindSingleByType(Customer.class);
+ Assertions.assertEquals("Donald", c.name());
+
+ // should not find anything
+ Assertions.assertThrows(NoSuchBeanTypeException.class,
+ () -> context.getRegistry().mandatoryFindSingleByType(UuidGenerator.class));
+ }
+
+}
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/MyService.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/MyService.java
new file mode 100644
index 00000000000..a458b2cca4b
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/primary/MyService.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.primary;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MyService {
+
+ @Bean
+ @Primary
+ public Customer goodCustomer() {
+ return new CustomerImpl("Donald");
+ }
+
+ @Bean
+ public Customer badCustomer() {
+ return new CustomerImpl("Jack");
+ }
+}
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/primary/findBySingle.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/primary/findBySingle.xml
new file mode 100644
index 00000000000..199b59ae39f
--- /dev/null
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/primary/findBySingle.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://camel.apache.org/schema/spring
+ http://camel.apache.org/schema/spring/camel-spring.xsd
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context.xsd">
+
+ <context:component-scan base-package="org.apache.camel.spring.primary"/>
+
+ <!-- empty -->
+ <camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring">
+ <jmxAgent id="jmx" disabled="true"/>
+ </camelContext>
+
+
+</beans>
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/ApplicationContextBeanRepository.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/ApplicationContextBeanRepository.java
index 95be7e1fcd9..fb1e2a2ee25 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/ApplicationContextBeanRepository.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/ApplicationContextBeanRepository.java
@@ -25,6 +25,7 @@ import org.apache.camel.spi.BeanRepository;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.NamedBeanHolder;
import org.springframework.context.ApplicationContext;
/**
@@ -83,4 +84,16 @@ public class ApplicationContextBeanRepository implements BeanRepository {
return BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, type);
}
+ @Override
+ public <T> T findSingleByType(Class<T> type) {
+ try {
+ // this API allows to support @Primary beans that should take precedence in
+ // case there are 2+ beans of the same type.
+ NamedBeanHolder<T> holder = applicationContext.getAutowireCapableBeanFactory().resolveNamedBean(type);
+ return holder.getBeanInstance();
+ } catch (NoSuchBeanDefinitionException e) {
+ return null;
+ }
+ }
+
}
diff --git a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java
index e5eda080e46..87140ea58b5 100644
--- a/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java
+++ b/components/camel-sql/src/generated/java/org/apache/camel/component/sql/stored/SqlStoredComponentConfigurer.java
@@ -31,6 +31,11 @@ public class SqlStoredComponentConfigurer extends PropertyConfigurerSupport impl
}
}
+ @Override
+ public String[] getAutowiredNames() {
+ return new String[]{"dataSource"};
+ }
+
@Override
public Class<?> getOptionType(String name, boolean ignoreCase) {
switch (ignoreCase ? name.toLowerCase() : name) {
diff --git a/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/stored/sql-stored.json b/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/stored/sql-stored.json
index 109ff9de0e7..db619b0c73b 100644
--- a/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/stored/sql-stored.json
+++ b/components/camel-sql/src/generated/resources/org/apache/camel/component/sql/stored/sql-stored.json
@@ -22,7 +22,7 @@
"lenientProperties": false
},
"componentProperties": {
- "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the DataSource to use to communicate with the database." },
+ "dataSource": { "index": 0, "kind": "property", "displayName": "Data Source", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "javax.sql.DataSource", "deprecated": false, "autowired": true, "secret": false, "description": "Sets the DataSource to use to communicate with the database." },
"lazyStartProducer": { "index": 1, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
"autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
},
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java
index 20754ab017b..1a4f329c8d8 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredComponent.java
@@ -17,7 +17,6 @@
package org.apache.camel.component.sql.stored;
import java.util.Map;
-import java.util.Set;
import javax.sql.DataSource;
@@ -36,45 +35,35 @@ public class SqlStoredComponent extends DefaultComponent {
private static final Logger LOG = LoggerFactory.getLogger(SqlStoredComponent.class);
- @Metadata
+ @Metadata(autowired = true)
private DataSource dataSource;
@Override
protected Endpoint createEndpoint(String uri, String template, Map<String, Object> parameters) throws Exception {
- DataSource target = null;
- // endpoint options overrule component configured datasource
- DataSource ds = resolveAndRemoveReferenceParameter(parameters, "dataSource", DataSource.class);
- if (ds != null) {
- target = ds;
- }
- if (target == null) {
- // fallback and use component
- target = dataSource;
- }
- if (target == null) {
- // check if the registry contains a single instance of DataSource
- Set<DataSource> dataSources = getCamelContext().getRegistry().findByType(DataSource.class);
- if (dataSources.size() > 1) {
- throw new IllegalArgumentException(
- "Multiple DataSources found in the registry and no explicit configuration provided");
- } else if (dataSources.size() == 1) {
- target = dataSources.iterator().next();
- }
+ SqlStoredEndpoint endpoint = new SqlStoredEndpoint(uri, this);
+ endpoint.setTemplate(template);
+ setProperties(endpoint, parameters);
+
+ // endpoint configured data source takes precedence
+ DataSource ds = dataSource;
+ if (endpoint.getDataSource() != null) {
+ ds = endpoint.getDataSource();
}
- if (target == null) {
+ if (ds == null) {
throw new IllegalArgumentException("DataSource must be configured");
}
- LOG.trace("Using DataSource: {}", target);
-
- JdbcTemplate jdbcTemplate = new JdbcTemplate(target);
+ // create template
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
Map<String, Object> templateOptions = PropertiesHelper.extractProperties(parameters, "template.");
PropertyBindingSupport.bindProperties(getCamelContext(), jdbcTemplate, templateOptions);
- SqlStoredEndpoint endpoint = new SqlStoredEndpoint(uri, this, jdbcTemplate);
- endpoint.setTemplate(template);
- setProperties(endpoint, parameters);
+ // set template on endpoint
+ endpoint.setJdbcTemplate(jdbcTemplate);
+ endpoint.setDataSource(ds);
+ endpoint.setTemplateOptions(templateOptions);
+
return endpoint;
}
diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
index 1f4c345042d..0f9b3622eb9 100644
--- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
+++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java
@@ -64,6 +64,10 @@ public class SqlStoredEndpoint extends DefaultEndpoint {
description = "Configures the Spring JdbcTemplate with the key/values from the Map")
private Map<String, Object> templateOptions;
+ public SqlStoredEndpoint(String uri, SqlStoredComponent component) {
+ super(uri, component);
+ }
+
public SqlStoredEndpoint(String uri, SqlStoredComponent component, JdbcTemplate jdbcTemplate) {
super(uri, component);
setJdbcTemplate(jdbcTemplate);
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java b/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
index fb875d2812f..ecb9ab93675 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BeanRepository.java
@@ -88,12 +88,11 @@ public interface BeanRepository {
* found.
*/
default <T> T mandatoryFindSingleByType(Class<T> type) {
- Set<T> set = findByType(type);
- if (set.size() == 1) {
- return set.iterator().next();
- } else {
- throw new NoSuchBeanTypeException(type, set.size());
+ T answer = findSingleByType(type);
+ if (answer == null) {
+ throw new NoSuchBeanTypeException(type);
}
+ return answer;
}
/**
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
index 0cdca505fae..dd52d5a6b07 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
@@ -342,6 +342,32 @@ public class DefaultRegistry extends ServiceSupport implements Registry, LocalBe
return answer;
}
+ @Override
+ public <T> T findSingleByType(Class<T> type) {
+ T found = null;
+
+ // local repository takes precedence
+ BeanRepository local = localRepositoryEnabled ? localRepository.get() : null;
+ if (local != null) {
+ found = local.findSingleByType(type);
+ }
+
+ if (found == null && repositories != null) {
+ for (BeanRepository r : repositories) {
+ found = r.findSingleByType(type);
+ }
+ }
+
+ if (found == null) {
+ found = supplierRegistry.findSingleByType(type);
+ }
+ if (found == null) {
+ found = fallbackRegistry.findSingleByType(type);
+ }
+
+ return found;
+ }
+
@Override
protected void doStop() throws Exception {
super.doStop();
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_2.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_2.adoc
index dca28e4a9a3..40457010611 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_2.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_2.adoc
@@ -39,8 +39,21 @@ expected to function correctly if using Java 21.
A new release of Apache Ignite is expected that will start to support Java 21.
-=== camel-spring-boot
+=== camel-spring & camel-spring-boot
+
+==== Autowiring Primary beans
+
+Camel will now take into account `@Primary` beans from Spring when autowiring by type.
+For example a JDBC `DataSource` in the SQL component will now use the `@Primary` data source
+when multiple data sources are defined.
+
+Previously Camel would not autowire if there are 2 or more beans for a given type.
+
+NOTE: This is a change in behaviour, that can affect your applications when upgrading.
+
+==== Properties
The `initialProperties` and `overrideProperties` on Camel `PropertiesComponent` will now
take precedence over Spring Boot properties. This can be used for testing purpose,
to allow overriding properties when using `CamelTestSupport` for unit testing.
+