mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-27 17:49:02 +00:00
Always invoke ConfigurationBeanNameGenerator
Previously, if a ConfigurationBeanNameGenerator is used to parse configuration classes, it is not invoked for `Bean` methods that provide a specific bean name. This doesn't give a chance to an implementation to tune such a bean, if required. This commit updates the signature of ConfigurationBeanNameGenerator to provide the identified bean name on the `@Bean` declaration,if any, and to always invoke it. Closes gh-35505
This commit is contained in:
+14
-7
@@ -45,17 +45,15 @@ abstract class BeanAnnotationHelper {
|
||||
|
||||
public static String determineBeanNameFor(Method beanMethod, ConfigurableBeanFactory beanFactory) {
|
||||
String beanName = retrieveBeanNameFor(beanMethod);
|
||||
if (!beanName.isEmpty()) {
|
||||
return beanName;
|
||||
if (beanFactory.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR)
|
||||
instanceof ConfigurationBeanNameGenerator cbng) {
|
||||
return cbng.deriveBeanName(MethodMetadata.introspect(beanMethod), (!beanName.isEmpty() ? beanName : null));
|
||||
}
|
||||
return (beanFactory.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR)
|
||||
instanceof ConfigurationBeanNameGenerator cbng ?
|
||||
cbng.deriveBeanName(MethodMetadata.introspect(beanMethod)) : beanMethod.getName());
|
||||
return determineBeanNameFrom(beanName, beanMethod);
|
||||
}
|
||||
|
||||
public static String determineBeanNameFor(Method beanMethod) {
|
||||
String beanName = retrieveBeanNameFor(beanMethod);
|
||||
return (!beanName.isEmpty() ? beanName : beanMethod.getName());
|
||||
return determineBeanNameFrom(retrieveBeanNameFor(beanMethod), beanMethod);
|
||||
}
|
||||
|
||||
private static String retrieveBeanNameFor(Method beanMethod) {
|
||||
@@ -77,6 +75,10 @@ abstract class BeanAnnotationHelper {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
private static String determineBeanNameFrom(String derivedBeanName, Method beanMethod) {
|
||||
return (!derivedBeanName.isEmpty() ? derivedBeanName : beanMethod.getName());
|
||||
}
|
||||
|
||||
public static boolean isScopedProxy(Method beanMethod) {
|
||||
Boolean scopedProxy = scopedProxyCache.get(beanMethod);
|
||||
if (scopedProxy == null) {
|
||||
@@ -88,4 +90,9 @@ abstract class BeanAnnotationHelper {
|
||||
return scopedProxy;
|
||||
}
|
||||
|
||||
static void clearCaches() {
|
||||
scopedProxyCache.clear();
|
||||
beanNameCache.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-4
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
|
||||
@@ -23,10 +25,10 @@ import org.springframework.core.type.MethodMetadata;
|
||||
* Extended variant of {@link BeanNameGenerator} for
|
||||
* {@link Configuration @Configuration} class purposes, not only covering
|
||||
* bean name generation for component and configuration classes themselves
|
||||
* but also for {@link Bean @Bean} methods without a {@link Bean#name() name}
|
||||
* attribute specified on the annotation itself.
|
||||
* but also for {@link Bean @Bean} methods.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 7.0
|
||||
* @see AnnotationConfigApplicationContext#setBeanNameGenerator
|
||||
* @see AnnotationConfigUtils#CONFIGURATION_BEAN_NAME_GENERATOR
|
||||
@@ -35,10 +37,11 @@ public interface ConfigurationBeanNameGenerator extends BeanNameGenerator {
|
||||
|
||||
/**
|
||||
* Derive a default bean name for the given {@link Bean @Bean} method,
|
||||
* in the absence of a {@link Bean#name() name} attribute specified.
|
||||
* providing the {@link Bean#name() name} attribute specified.
|
||||
* @param beanMethod the method metadata for the {@link Bean @Bean} method
|
||||
* @param beanName the {@link Bean#name() name} attribute or {@code null} if non is specified
|
||||
* @return the default bean name to use
|
||||
*/
|
||||
String deriveBeanName(MethodMetadata beanMethod);
|
||||
String deriveBeanName(MethodMetadata beanMethod, @Nullable String beanName);
|
||||
|
||||
}
|
||||
|
||||
+9
-11
@@ -197,22 +197,16 @@ class ConfigurationClassBeanDefinitionReader {
|
||||
|
||||
// Consider name and any aliases.
|
||||
String[] explicitNames = bean.getStringArray("name");
|
||||
String beanName;
|
||||
String localBeanName;
|
||||
if (explicitNames.length > 0 && StringUtils.hasText(explicitNames[0])) {
|
||||
beanName = explicitNames[0];
|
||||
localBeanName = beanName;
|
||||
String beanName = (explicitNames.length > 0 && StringUtils.hasText(explicitNames[0])) ? explicitNames[0] : null;
|
||||
String localBeanName = defaultBeanName(beanName, methodName);
|
||||
beanName = (this.importBeanNameGenerator instanceof ConfigurationBeanNameGenerator cbng ?
|
||||
cbng.deriveBeanName(metadata, beanName) : defaultBeanName(beanName, methodName));
|
||||
if (explicitNames.length > 0) {
|
||||
// Register aliases even when overridden below.
|
||||
for (int i = 1; i < explicitNames.length; i++) {
|
||||
this.registry.registerAlias(beanName, explicitNames[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Default bean name derived from method name.
|
||||
beanName = (this.importBeanNameGenerator instanceof ConfigurationBeanNameGenerator cbng ?
|
||||
cbng.deriveBeanName(metadata) : methodName);
|
||||
localBeanName = methodName;
|
||||
}
|
||||
|
||||
ConfigurationClassBeanDefinition beanDef =
|
||||
new ConfigurationClassBeanDefinition(configClass, metadata, localBeanName);
|
||||
@@ -306,6 +300,10 @@ class ConfigurationClassBeanDefinitionReader {
|
||||
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
|
||||
}
|
||||
|
||||
private static String defaultBeanName(@Nullable String beanName, String methodName) {
|
||||
return (beanName != null ? beanName : methodName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullAway") // Reflection
|
||||
private boolean isOverriddenByExistingDefinition(
|
||||
BeanMethod beanMethod, String beanName, ConfigurationClassBeanDefinition newBeanDef) {
|
||||
|
||||
+6
-4
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
|
||||
/**
|
||||
@@ -23,8 +25,8 @@ import org.springframework.core.type.MethodMetadata;
|
||||
* {@link Configuration @Configuration} class purposes, not only enforcing
|
||||
* fully-qualified names for component and configuration classes themselves
|
||||
* but also fully-qualified default bean names ("className.methodName") for
|
||||
* {@link Bean @Bean} methods. This only affects methods without an explicit
|
||||
* {@link Bean#name() name} attribute specified.
|
||||
* {@link Bean @Bean} methods. By default, this only affects methods without
|
||||
* an explicit {@link Bean#name() name} attribute specified.
|
||||
*
|
||||
* <p>This provides an alternative to the default bean name generation for
|
||||
* {@code @Bean} methods (which uses the plain method name), primarily for use
|
||||
@@ -54,8 +56,8 @@ public class FullyQualifiedConfigurationBeanNameGenerator extends FullyQualified
|
||||
|
||||
|
||||
@Override
|
||||
public String deriveBeanName(MethodMetadata beanMethod) {
|
||||
return beanMethod.getDeclaringClassName() + "." + beanMethod.getMethodName();
|
||||
public String deriveBeanName(MethodMetadata beanMethod, @Nullable String beanName) {
|
||||
return (beanName != null ? beanName : beanMethod.getDeclaringClassName() + "." + beanMethod.getMethodName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user