Avoid early singleton inference outside of original creation thread
See gh-23501
This commit is contained in:
		
							parent
							
								
									902e5707a8
								
							
						
					
					
						commit
						4a02893c31
					
				|  | @ -188,7 +188,10 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements | ||||||
| 		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { | 		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { | ||||||
| 			singletonObject = this.earlySingletonObjects.get(beanName); | 			singletonObject = this.earlySingletonObjects.get(beanName); | ||||||
| 			if (singletonObject == null && allowEarlyReference) { | 			if (singletonObject == null && allowEarlyReference) { | ||||||
| 				this.singletonLock.lock(); | 				if (!this.singletonLock.tryLock()) { | ||||||
|  | 					// Avoid early singleton inference outside of original creation thread | ||||||
|  | 					return null; | ||||||
|  | 				} | ||||||
| 				try { | 				try { | ||||||
| 					// Consistent creation of early reference within full singleton lock | 					// Consistent creation of early reference within full singleton lock | ||||||
| 					singletonObject = this.singletonObjects.get(beanName); | 					singletonObject = this.singletonObjects.get(beanName); | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory; | ||||||
| import org.springframework.beans.factory.support.RootBeanDefinition; | import org.springframework.beans.factory.support.RootBeanDefinition; | ||||||
| import org.springframework.beans.testfixture.beans.TestBean; | import org.springframework.beans.testfixture.beans.TestBean; | ||||||
| 
 | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * @author Juergen Hoeller |  * @author Juergen Hoeller | ||||||
|  * @since 6.2 |  * @since 6.2 | ||||||
|  | @ -31,8 +34,10 @@ class BeanFactoryLockingTests { | ||||||
| 	@Test | 	@Test | ||||||
| 	void fallbackForThreadDuringInitialization() { | 	void fallbackForThreadDuringInitialization() { | ||||||
| 		DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); | 		DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); | ||||||
| 		beanFactory.registerBeanDefinition("bean1", new RootBeanDefinition(ThreadDuringInitialization.class)); | 		beanFactory.registerBeanDefinition("bean1", | ||||||
| 		beanFactory.registerBeanDefinition("bean2", new RootBeanDefinition(TestBean.class)); | 				new RootBeanDefinition(ThreadDuringInitialization.class)); | ||||||
|  | 		beanFactory.registerBeanDefinition("bean2", | ||||||
|  | 				new RootBeanDefinition(TestBean.class, () -> new TestBean("tb"))); | ||||||
| 		beanFactory.getBean(ThreadDuringInitialization.class); | 		beanFactory.getBean(ThreadDuringInitialization.class); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -51,7 +56,12 @@ class BeanFactoryLockingTests { | ||||||
| 		@Override | 		@Override | ||||||
| 		public void afterPropertiesSet() throws Exception { | 		public void afterPropertiesSet() throws Exception { | ||||||
| 			Thread thread = new Thread(() -> { | 			Thread thread = new Thread(() -> { | ||||||
| 				beanFactory.getBean(TestBean.class); | 				// Fail for circular reference from other thread | ||||||
|  | 				assertThatExceptionOfType(BeanCurrentlyInCreationException.class).isThrownBy(() -> | ||||||
|  | 						beanFactory.getBean(ThreadDuringInitialization.class)); | ||||||
|  | 				// Leniently create unrelated other bean outside of singleton lock | ||||||
|  | 				assertThat(beanFactory.getBean(TestBean.class).getName()).isEqualTo("tb"); | ||||||
|  | 				// Creation attempt in other thread was successful | ||||||
| 				initialized = true; | 				initialized = true; | ||||||
| 			}); | 			}); | ||||||
| 			thread.start(); | 			thread.start(); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue