Skip to content

Commit 11330ba

Browse files
committed
DefaultListableBeanFactory checks for alias circle on registerAlias (avoiding endless loop; SPR-7274)
1 parent 433b4ef commit 11330ba

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,20 @@ private void testSingleTestBean(ListableBeanFactory lbf) {
723723
assertTrue("Test bean age is 48", tb.getAge() == 48);
724724
}
725725

726+
@Test
727+
public void testAliasCircle() {
728+
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
729+
lbf.registerAlias("test", "test2");
730+
lbf.registerAlias("test2", "test3");
731+
try {
732+
lbf.registerAlias("test3", "test");
733+
fail("Should have thrown IllegalStateException");
734+
}
735+
catch (IllegalStateException ex) {
736+
// expected
737+
}
738+
}
739+
726740
@Test
727741
public void testBeanDefinitionOverriding() {
728742
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();

org.springframework.core/src/main/java/org/springframework/core/SimpleAliasRegistry.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public void registerAlias(String name, String alias) {
5555
name + "': It is already registered for name '" + registeredName + "'.");
5656
}
5757
}
58+
checkForAliasCircle(name, alias);
5859
this.aliasMap.put(alias, name);
5960
}
6061
}
@@ -128,6 +129,7 @@ else if (!resolvedAlias.equals(alias)) {
128129
"') for name '" + resolvedName + "': It is already registered for name '" +
129130
registeredName + "'.");
130131
}
132+
checkForAliasCircle(resolvedName, resolvedAlias);
131133
this.aliasMap.remove(alias);
132134
this.aliasMap.put(resolvedAlias, resolvedName);
133135
}
@@ -157,4 +159,20 @@ public String canonicalName(String name) {
157159
return canonicalName;
158160
}
159161

162+
/**
163+
* Check whether the given name points back to given alias as an alias
164+
* in the other direction, catching a circular reference upfront and
165+
* throwing a corresponding IllegalStateException.
166+
* @param name the candidate name
167+
* @param alias the candidate alias
168+
* @see #registerAlias
169+
*/
170+
protected void checkForAliasCircle(String name, String alias) {
171+
if (alias.equals(canonicalName(name))) {
172+
throw new IllegalStateException("Cannot register alias '" + alias +
173+
"' for name '" + name + "': Circular reference - '" +
174+
name + "' is a direct or indirect alias for '" + alias + "' already");
175+
}
176+
}
177+
160178
}

0 commit comments

Comments
 (0)