Merge branch '6.2.x'

This commit is contained in:
Sam Brannen 2025-04-04 15:54:29 +02:00
commit 5b4511fbf7
8 changed files with 29 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2025 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -112,10 +112,10 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass); boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
for (String mappedName : this.beanNames) { for (String mappedName : this.beanNames) {
if (isFactoryBean) { if (isFactoryBean) {
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { if (mappedName.isEmpty() || mappedName.charAt(0) != BeanFactory.FACTORY_BEAN_PREFIX_CHAR) {
continue; continue;
} }
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); mappedName = mappedName.substring(1); // length of '&'
} }
if (isMatch(beanName, mappedName)) { if (isMatch(beanName, mappedName)) {
return true; return true;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -125,9 +125,16 @@ public interface BeanFactory {
* beans <i>created</i> by the FactoryBean. For example, if the bean named * beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory. * will return the factory, not the instance returned by the factory.
* @see #FACTORY_BEAN_PREFIX_CHAR
*/ */
String FACTORY_BEAN_PREFIX = "&"; String FACTORY_BEAN_PREFIX = "&";
/**
* Character variant of {@link #FACTORY_BEAN_PREFIX}.
* @since 6.2.6
*/
char FACTORY_BEAN_PREFIX_CHAR = '&';
/** /**
* Return an instance, which may be shared or independent, of the specified bean. * Return an instance, which may be shared or independent, of the specified bean.

View File

@ -73,7 +73,7 @@ public abstract class BeanFactoryUtils {
* @see BeanFactory#FACTORY_BEAN_PREFIX * @see BeanFactory#FACTORY_BEAN_PREFIX
*/ */
public static boolean isFactoryDereference(@Nullable String name) { public static boolean isFactoryDereference(@Nullable String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); return (name != null && !name.isEmpty() && name.charAt(0) == BeanFactory.FACTORY_BEAN_PREFIX_CHAR);
} }
/** /**
@ -85,14 +85,14 @@ public abstract class BeanFactoryUtils {
*/ */
public static String transformedBeanName(String name) { public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null"); Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { if (name.isEmpty() || name.charAt(0) != BeanFactory.FACTORY_BEAN_PREFIX_CHAR) {
return name; return name;
} }
return transformedBeanNameCache.computeIfAbsent(name, beanName -> { return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do { do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); beanName = beanName.substring(1); // length of '&'
} }
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); while (beanName.charAt(0) == BeanFactory.FACTORY_BEAN_PREFIX_CHAR);
return beanName; return beanName;
}); });
} }

View File

@ -762,16 +762,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
public String[] getAliases(String name) { public String[] getAliases(String name) {
String beanName = transformedBeanName(name); String beanName = transformedBeanName(name);
List<String> aliases = new ArrayList<>(); List<String> aliases = new ArrayList<>();
boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX); boolean hasFactoryPrefix = (!name.isEmpty() && name.charAt(0) == BeanFactory.FACTORY_BEAN_PREFIX_CHAR);
String fullBeanName = beanName; String fullBeanName = beanName;
if (factoryPrefix) { if (hasFactoryPrefix) {
fullBeanName = FACTORY_BEAN_PREFIX + beanName; fullBeanName = FACTORY_BEAN_PREFIX + beanName;
} }
if (!fullBeanName.equals(name)) { if (!fullBeanName.equals(name)) {
aliases.add(fullBeanName); aliases.add(fullBeanName);
} }
String[] retrievedAliases = super.getAliases(beanName); String[] retrievedAliases = super.getAliases(beanName);
String prefix = (factoryPrefix ? FACTORY_BEAN_PREFIX : ""); String prefix = (hasFactoryPrefix ? FACTORY_BEAN_PREFIX : "");
for (String retrievedAlias : retrievedAliases) { for (String retrievedAlias : retrievedAliases) {
String alias = prefix + retrievedAlias; String alias = prefix + retrievedAlias;
if (!alias.equals(name)) { if (!alias.equals(name)) {
@ -1137,7 +1137,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException { public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name); String beanName = transformedBeanName(name);
// Efficiently check whether bean definition exists in this factory. // Efficiently check whether bean definition exists in this factory.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory parent) { if (getParentBeanFactory() instanceof ConfigurableBeanFactory parent && !containsBeanDefinition(beanName)) {
return parent.getMergedBeanDefinition(beanName); return parent.getMergedBeanDefinition(beanName);
} }
// Resolve merged bean definition locally. // Resolve merged bean definition locally.
@ -1276,7 +1276,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
*/ */
protected String originalBeanName(String name) { protected String originalBeanName(String name) {
String beanName = transformedBeanName(name); String beanName = transformedBeanName(name);
if (name.startsWith(FACTORY_BEAN_PREFIX)) { if (!name.isEmpty() && name.charAt(0) == BeanFactory.FACTORY_BEAN_PREFIX_CHAR) {
beanName = FACTORY_BEAN_PREFIX + beanName; beanName = FACTORY_BEAN_PREFIX + beanName;
} }
return beanName; return beanName;

View File

@ -362,9 +362,9 @@ class ConfigurationClassEnhancer {
// proxy that intercepts calls to getObject() and returns any cached bean instance. // proxy that intercepts calls to getObject() and returns any cached bean instance.
// This ensures that the semantics of calling a FactoryBean from within @Bean methods // This ensures that the semantics of calling a FactoryBean from within @Bean methods
// is the same as that of referring to a FactoryBean within XML. See SPR-6602. // is the same as that of referring to a FactoryBean within XML. See SPR-6602.
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) && String factoryBeanName = BeanFactory.FACTORY_BEAN_PREFIX + beanName;
factoryContainsBean(beanFactory, beanName)) { if (factoryContainsBean(beanFactory, factoryBeanName) && factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName); Object factoryBean = beanFactory.getBean(factoryBeanName);
if (factoryBean instanceof ScopedProxyFactoryBean) { if (factoryBean instanceof ScopedProxyFactoryBean) {
// Scoped proxy factory beans are a special case and should not be further proxied // Scoped proxy factory beans are a special case and should not be further proxied
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2024 the original author or authors. * Copyright 2002-2025 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -926,8 +926,8 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
*/ */
private boolean isExcluded(String beanName) { private boolean isExcluded(String beanName) {
return (this.excludedBeans.contains(beanName) || return (this.excludedBeans.contains(beanName) ||
(beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX) && (!beanName.isEmpty() && (beanName.charAt(0) == BeanFactory.FACTORY_BEAN_PREFIX_CHAR) &&
this.excludedBeans.contains(beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length())))); this.excludedBeans.contains(beanName.substring(1)))); // length of '&'
} }
/** /**

View File

@ -350,6 +350,7 @@ abstract class AnnotationsScanner {
private static boolean isOverride(Method rootMethod, Method candidateMethod) { private static boolean isOverride(Method rootMethod, Method candidateMethod) {
return (!Modifier.isPrivate(candidateMethod.getModifiers()) && return (!Modifier.isPrivate(candidateMethod.getModifiers()) &&
candidateMethod.getParameterCount() == rootMethod.getParameterCount() &&
candidateMethod.getName().equals(rootMethod.getName()) && candidateMethod.getName().equals(rootMethod.getName()) &&
hasSameParameterTypes(rootMethod, candidateMethod)); hasSameParameterTypes(rootMethod, candidateMethod));
} }

View File

@ -614,10 +614,11 @@ public abstract class ClassUtils {
Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType); Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType);
return (lhsType == resolvedPrimitive); return (lhsType == resolvedPrimitive);
} }
else { else if (rhsType.isPrimitive()) {
Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType); Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType);
return (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)); return (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper));
} }
return false;
} }
/** /**