Skip to content

Commit 182243d

Browse files
committed
BeanDefinitionOverrideException in case of overriding not allowed
Issue: SPR-16982
1 parent 63d6215 commit 182243d

File tree

5 files changed

+122
-28
lines changed

5 files changed

+122
-28
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/BeanDefinitionStoreException.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public BeanDefinitionStoreException(@Nullable String resourceDescription, String
8484
/**
8585
* Create a new BeanDefinitionStoreException.
8686
* @param resourceDescription description of the resource that the bean definition came from
87-
* @param beanName the name of the bean requested
87+
* @param beanName the name of the bean
8888
* @param msg the detail message (appended to an introductory message that indicates
8989
* the resource and the name of the bean)
9090
*/
@@ -95,29 +95,31 @@ public BeanDefinitionStoreException(@Nullable String resourceDescription, String
9595
/**
9696
* Create a new BeanDefinitionStoreException.
9797
* @param resourceDescription description of the resource that the bean definition came from
98-
* @param beanName the name of the bean requested
98+
* @param beanName the name of the bean
9999
* @param msg the detail message (appended to an introductory message that indicates
100100
* the resource and the name of the bean)
101101
* @param cause the root cause (may be {@code null})
102102
*/
103-
public BeanDefinitionStoreException(@Nullable String resourceDescription, String beanName, String msg, @Nullable Throwable cause) {
104-
super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg, cause);
103+
public BeanDefinitionStoreException(
104+
@Nullable String resourceDescription, String beanName, String msg, @Nullable Throwable cause) {
105+
106+
super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg,
107+
cause);
105108
this.resourceDescription = resourceDescription;
106109
this.beanName = beanName;
107110
}
108111

109112

110113
/**
111-
* Return the description of the resource that the bean
112-
* definition came from, if any.
114+
* Return the description of the resource that the bean definition came from, if available.
113115
*/
114116
@Nullable
115117
public String getResourceDescription() {
116118
return this.resourceDescription;
117119
}
118120

119121
/**
120-
* Return the name of the bean requested, if any.
122+
* Return the name of the bean, if available.
121123
*/
122124
@Nullable
123125
public String getBeanName() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright 2002-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.beans.factory.support;
18+
19+
import org.springframework.beans.factory.BeanDefinitionStoreException;
20+
import org.springframework.beans.factory.config.BeanDefinition;
21+
import org.springframework.lang.NonNull;
22+
23+
/**
24+
* Subclass of {@link BeanDefinitionStoreException} indicating an invalid override
25+
* attempt: typically registering a new definition for the same bean name while
26+
* {@link DefaultListableBeanFactory#isAllowBeanDefinitionOverriding()} is {@code false}.
27+
*
28+
* @author Juergen Hoeller
29+
* @since 5.1
30+
* @see DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
31+
* @see DefaultListableBeanFactory#registerBeanDefinition
32+
*/
33+
public class BeanDefinitionOverrideException extends BeanDefinitionStoreException {
34+
35+
private final BeanDefinition beanDefinition;
36+
37+
private final BeanDefinition existingDefinition;
38+
39+
40+
/**
41+
* Create a new BeanDefinitionOverrideException for the given new and existing definition.
42+
* @param beanName the name of the bean
43+
* @param beanDefinition the newly registered bean definition
44+
* @param existingDefinition the existing bean definition for the same name
45+
*/
46+
public BeanDefinitionOverrideException(
47+
String beanName, BeanDefinition beanDefinition, BeanDefinition existingDefinition) {
48+
49+
super(beanDefinition.getResourceDescription(), beanName,
50+
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
51+
"': There is already [" + existingDefinition + "] bound.");
52+
this.beanDefinition = beanDefinition;
53+
this.existingDefinition = existingDefinition;
54+
}
55+
56+
57+
/**
58+
* Return the description of the resource that the bean definition came from.
59+
*/
60+
@Override
61+
@NonNull
62+
public String getResourceDescription() {
63+
return String.valueOf(super.getResourceDescription());
64+
}
65+
66+
/**
67+
* Return the name of the bean.
68+
*/
69+
@Override
70+
@NonNull
71+
public String getBeanName() {
72+
return String.valueOf(super.getBeanName());
73+
}
74+
75+
/**
76+
* Return the newly registered bean definition.
77+
* @see #getBeanName()
78+
*/
79+
public BeanDefinition getBeanDefinition() {
80+
return this.beanDefinition;
81+
}
82+
83+
/**
84+
* Return the existing bean definition for the same name.
85+
* @see #getBeanName()
86+
*/
87+
public BeanDefinition getExistingDefinition() {
88+
return this.existingDefinition;
89+
}
90+
91+
}

spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionRegistry.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,8 +53,9 @@ public interface BeanDefinitionRegistry extends AliasRegistry {
5353
* @param beanName the name of the bean instance to register
5454
* @param beanDefinition definition of the bean instance to register
5555
* @throws BeanDefinitionStoreException if the BeanDefinition is invalid
56-
* or if there is already a BeanDefinition for the specified bean name
57-
* (and we are not allowed to override it)
56+
* @throws BeanDefinitionOverrideException if there is already a BeanDefinition
57+
* for the specified bean name and we are not allowed to override it
58+
* @see GenericBeanDefinition
5859
* @see RootBeanDefinition
5960
* @see ChildBeanDefinition
6061
*/

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -802,34 +802,30 @@ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinitio
802802
}
803803
}
804804

805-
BeanDefinition oldBeanDefinition;
806-
807-
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
808-
if (oldBeanDefinition != null) {
805+
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
806+
if (existingDefinition != null) {
809807
if (!isAllowBeanDefinitionOverriding()) {
810-
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
811-
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
812-
"': There is already [" + oldBeanDefinition + "] bound.");
808+
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
813809
}
814-
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
810+
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
815811
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
816812
if (logger.isWarnEnabled()) {
817813
logger.warn("Overriding user-defined bean definition for bean '" + beanName +
818814
"' with a framework-generated bean definition: replacing [" +
819-
oldBeanDefinition + "] with [" + beanDefinition + "]");
815+
existingDefinition + "] with [" + beanDefinition + "]");
820816
}
821817
}
822-
else if (!beanDefinition.equals(oldBeanDefinition)) {
818+
else if (!beanDefinition.equals(existingDefinition)) {
823819
if (logger.isInfoEnabled()) {
824820
logger.info("Overriding bean definition for bean '" + beanName +
825-
"' with a different definition: replacing [" + oldBeanDefinition +
821+
"' with a different definition: replacing [" + existingDefinition +
826822
"] with [" + beanDefinition + "]");
827823
}
828824
}
829825
else {
830826
if (logger.isDebugEnabled()) {
831827
logger.debug("Overriding bean definition for bean '" + beanName +
832-
"' with an equivalent definition: replacing [" + oldBeanDefinition +
828+
"' with an equivalent definition: replacing [" + existingDefinition +
833829
"] with [" + beanDefinition + "]");
834830
}
835831
}
@@ -860,7 +856,7 @@ else if (!beanDefinition.equals(oldBeanDefinition)) {
860856
this.frozenBeanDefinitionNames = null;
861857
}
862858

863-
if (oldBeanDefinition != null || containsSingleton(beanName)) {
859+
if (existingDefinition != null || containsSingleton(beanName)) {
864860
resetBeanDefinition(beanName);
865861
}
866862
}

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import org.springframework.beans.factory.support.AbstractBeanDefinition;
6969
import org.springframework.beans.factory.support.AbstractBeanFactory;
7070
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
71+
import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
7172
import org.springframework.beans.factory.support.ChildBeanDefinition;
7273
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
7374
import org.springframework.beans.factory.support.ManagedList;
@@ -841,14 +842,17 @@ public void testBeanDefinitionRemoval() {
841842
public void testBeanDefinitionOverridingNotAllowed() {
842843
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
843844
lbf.setAllowBeanDefinitionOverriding(false);
844-
lbf.registerBeanDefinition("test", new RootBeanDefinition(TestBean.class));
845+
BeanDefinition oldDef = new RootBeanDefinition(TestBean.class);
846+
BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class);
847+
lbf.registerBeanDefinition("test", oldDef);
845848
try {
846-
lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class));
847-
fail("Should have thrown BeanDefinitionStoreException");
849+
lbf.registerBeanDefinition("test", newDef);
850+
fail("Should have thrown BeanDefinitionOverrideException");
848851
}
849-
catch (BeanDefinitionStoreException ex) {
852+
catch (BeanDefinitionOverrideException ex) {
850853
assertEquals("test", ex.getBeanName());
851-
// expected
854+
assertSame(newDef, ex.getBeanDefinition());
855+
assertSame(oldDef, ex.getExistingDefinition());
852856
}
853857
}
854858

0 commit comments

Comments
 (0)