diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java
index 07976017703..24227a3c114 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,10 +39,14 @@ import org.springframework.util.StringUtils;
* (which the methods defined on the ListableBeanFactory interface don't,
* in contrast to the methods defined on the BeanFactory interface).
*
+ *
NOTE: It is generally preferable to use {@link ObjectProvider#stream()}
+ * via {@link BeanFactory#getBeanProvider} instead of this utility class.
+ *
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 04.07.2003
+ * @see BeanFactory#getBeanProvider
*/
public abstract class BeanFactoryUtils {
@@ -308,7 +312,7 @@ public abstract class BeanFactoryUtils {
* 'replacing' beans by explicitly choosing the same bean name in a child factory;
* the bean in the ancestor factory won't be visible then, not even for by-type lookups.
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @return the Map of matching bean instances, or an empty Map if none
* @throws BeansException if a bean could not be created
* @see ListableBeanFactory#getBeansOfType(Class)
@@ -347,7 +351,7 @@ public abstract class BeanFactoryUtils {
* 'replacing' beans by explicitly choosing the same bean name in a child factory;
* the bean in the ancestor factory won't be visible then, not even for by-type lookups.
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize lazy-init singletons and
@@ -395,7 +399,7 @@ public abstract class BeanFactoryUtils {
* 'replacing' beans by explicitly choosing the same bean name in a child factory;
* the bean in the ancestor factory won't be visible then, not even for by-type lookups.
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @return the matching bean instance
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
@@ -425,7 +429,7 @@ public abstract class BeanFactoryUtils {
* 'replacing' beans by explicitly choosing the same bean name in a child factory;
* the bean in the ancestor factory won't be visible then, not even for by-type lookups.
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize lazy-init singletons and
@@ -457,7 +461,7 @@ public abstract class BeanFactoryUtils {
*
This version of {@code beanOfType} automatically includes
* prototypes and FactoryBeans.
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @return the matching bean instance
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
@@ -481,7 +485,7 @@ public abstract class BeanFactoryUtils {
* only raw FactoryBeans will be checked (which doesn't require initialization
* of each FactoryBean).
* @param lbf the bean factory
- * @param type type of bean to match
+ * @param type the type of bean to match
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize lazy-init singletons and
@@ -529,7 +533,7 @@ public abstract class BeanFactoryUtils {
/**
* Extract a unique bean for the given type from the given Map of matching beans.
- * @param type type of bean to match
+ * @param type the type of bean to match
* @param matchingBeans all matching beans found
* @return the unique bean instance
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java
index 6127fd79566..492d224a9cb 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/ObjectProvider.java
@@ -55,10 +55,13 @@ import org.springframework.lang.Nullable;
public interface ObjectProvider extends ObjectFactory, Iterable {
/**
- * A predicate for unfiltered type matches.
+ * A predicate for unfiltered type matches, including non-default candidates
+ * but still excluding non-autowire candidates when used on injection points.
* @since 6.2.3
* @see #stream(Predicate)
* @see #orderedStream(Predicate)
+ * @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
+ * @see org.springframework.beans.factory.support.AbstractBeanDefinition#isDefaultCandidate()
*/
Predicate> UNFILTERED = (clazz -> true);
@@ -210,7 +213,7 @@ public interface ObjectProvider extends ObjectFactory, Iterable {
* without specific ordering guarantees (but typically in registration order).
*
Note: The result may be filtered by default according to qualifiers on the
* injection point versus target beans and the general autowire candidate status
- * of matching beans. For custom filtering against the raw type matches, use
+ * of matching beans. For custom filtering against type-matching candidates, use
* {@link #stream(Predicate)} instead (potentially with {@link #UNFILTERED}).
* @since 5.1
* @see #iterator()
@@ -235,7 +238,7 @@ public interface ObjectProvider extends ObjectFactory, Iterable {
* if necessary.
*
Note: The result may be filtered by default according to qualifiers on the
* injection point versus target beans and the general autowire candidate status
- * of matching beans. For custom filtering against the raw type matches, use
+ * of matching beans. For custom filtering against type-matching candidates, use
* {@link #stream(Predicate)} instead (potentially with {@link #UNFILTERED}).
* @since 5.1
* @see #stream()
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
index 1a6f0c87533..246735bc41e 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@ import java.util.Comparator;
import java.util.Set;
import org.springframework.beans.BeanMetadataElement;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -259,6 +261,24 @@ abstract class AutowireUtils {
return method.getReturnType();
}
+ /**
+ * Check the autowire-candidate status for the specified bean.
+ * @param beanFactory the bean factory
+ * @param beanName the name of the bean to check
+ * @return whether the specified bean qualifies as an autowire candidate
+ * @since 6.2.3
+ * @see org.springframework.beans.factory.config.BeanDefinition#isAutowireCandidate()
+ */
+ public static boolean isAutowireCandidate(ConfigurableBeanFactory beanFactory, String beanName) {
+ try {
+ return beanFactory.getMergedBeanDefinition(beanName).isAutowireCandidate();
+ }
+ catch (NoSuchBeanDefinitionException ex) {
+ // A manually registered singleton instance not backed by a BeanDefinition.
+ return true;
+ }
+ }
+
/**
* Reflective {@link InvocationHandler} for lazy access to the current target object.
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
index 26ec8b9496b..54df257fe6f 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java
@@ -2516,6 +2516,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
@Override
public Stream