diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionOverrideException.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionOverrideException.java index c2c6281b7f9..f894298b151 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionOverrideException.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionOverrideException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +49,7 @@ public class BeanDefinitionOverrideException extends BeanDefinitionStoreExceptio super(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + - "': There is already [" + existingDefinition + "] bound."); + "' since there is already [" + existingDefinition + "] bound."); this.beanDefinition = beanDefinition; this.existingDefinition = existingDefinition; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 4186000c303..8deda89418c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -994,6 +994,23 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto this.beanDefinitionMap.put(beanName, beanDefinition); } else { + if (isAlias(beanName)) { + if (!isAllowBeanDefinitionOverriding()) { + String aliasedName = canonicalName(beanName); + if (containsBeanDefinition(aliasedName)) { // alias for existing bean definition + throw new BeanDefinitionOverrideException( + beanName, beanDefinition, getBeanDefinition(aliasedName)); + } + else { // alias pointing to non-existing bean definition + throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, + "Cannot register bean definition for bean '" + beanName + + "' since there is already an alias for bean '" + aliasedName + "' bound."); + } + } + else { + removeAlias(beanName); + } + } if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java index 8439900f3e0..27e81f1577b 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java @@ -854,8 +854,11 @@ class DefaultListableBeanFactoryTests { lbf.registerBeanDefinition("test", new RootBeanDefinition(NestedTestBean.class)); lbf.registerAlias("otherTest", "test2"); lbf.registerAlias("test", "test2"); + lbf.registerAlias("test", "testX"); + lbf.registerBeanDefinition("testX", new RootBeanDefinition(TestBean.class)); assertThat(lbf.getBean("test")).isInstanceOf(NestedTestBean.class); assertThat(lbf.getBean("test2")).isInstanceOf(NestedTestBean.class); + assertThat(lbf.getBean("testX")).isInstanceOf(TestBean.class); } @Test @@ -864,6 +867,7 @@ class DefaultListableBeanFactoryTests { BeanDefinition oldDef = new RootBeanDefinition(TestBean.class); BeanDefinition newDef = new RootBeanDefinition(NestedTestBean.class); lbf.registerBeanDefinition("test", oldDef); + lbf.registerAlias("test", "testX"); assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() -> lbf.registerBeanDefinition("test", newDef)) .satisfies(ex -> { @@ -871,6 +875,13 @@ class DefaultListableBeanFactoryTests { assertThat(ex.getBeanDefinition()).isEqualTo(newDef); assertThat(ex.getExistingDefinition()).isEqualTo(oldDef); }); + assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() -> + lbf.registerBeanDefinition("testX", newDef)) + .satisfies(ex -> { + assertThat(ex.getBeanName()).isEqualTo("testX"); + assertThat(ex.getBeanDefinition()).isEqualTo(newDef); + assertThat(ex.getExistingDefinition()).isEqualTo(oldDef); + }); } @Test