Make use of bean definition overriding more visible

This commit makes the use of bean definition overriding more visible and
prepare for a deprecation of the feature in the next major release.

As of this commit, use of bean definition overriding logs at INFO level.
The previous log level can be restored by setting the
allowBeanDefinitionOverriding flag explicitly on the BeanFactory (or
via the related ApplicationContext).

A number of tests that are using bean overriding on purpose have been
updated to set this flag, which will make them easier to find once we
actually deprecate the feature.

Closes gh-31288
This commit is contained in:
Stéphane Nicoll
2024-03-25 09:53:18 +01:00
parent 8af3eb1aea
commit 7a74e45946
17 changed files with 186 additions and 71 deletions

View File

@@ -152,7 +152,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private String serializationId;
/** Whether to allow re-registration of a different definition with the same name. */
private boolean allowBeanDefinitionOverriding = true;
@Nullable
private Boolean allowBeanDefinitionOverriding;
/** Whether to allow eager class loading even for lazy-init beans. */
private boolean allowEagerClassLoading = true;
@@ -259,7 +260,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* @since 4.1.2
*/
public boolean isAllowBeanDefinitionOverriding() {
return this.allowBeanDefinitionOverriding;
return !Boolean.FALSE.equals(this.allowBeanDefinitionOverriding);
}
/**
@@ -1142,27 +1143,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (!isBeanDefinitionOverridable(beanName)) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
logBeanDefinitionOverriding(beanName, beanDefinition, existingDefinition);
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@@ -1217,6 +1199,44 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
private void logBeanDefinitionOverriding(String beanName, BeanDefinition beanDefinition,
BeanDefinition existingDefinition) {
boolean explicitBeanOverride = (this.allowBeanDefinitionOverriding != null);
if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (explicitBeanOverride && logger.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (explicitBeanOverride && logger.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
}
@Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
Assert.hasText(beanName, "'beanName' must not be empty");