Wait for lenient bean creation in locked thread when necessary
Closes gh-34349
This commit is contained in:
@@ -19,14 +19,12 @@ package org.springframework.context.annotation;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.Timeout;
|
||||
|
||||
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.testfixture.beans.TestBean;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.testfixture.EnabledForTestGroups;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.springframework.context.annotation.Bean.Bootstrap.BACKGROUND;
|
||||
import static org.springframework.core.testfixture.TestGroup.LONG_RUNNING;
|
||||
|
||||
@@ -42,8 +40,19 @@ class BackgroundBootstrapTests {
|
||||
void bootstrapWithUnmanagedThread() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(UnmanagedThreadBeanConfig.class);
|
||||
ctx.getBean("testBean1", TestBean.class);
|
||||
assertThatExceptionOfType(BeanCurrentlyInCreationException.class).isThrownBy( // late - not during refresh
|
||||
() -> ctx.getBean("testBean2", TestBean.class));
|
||||
ctx.getBean("testBean2", TestBean.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(5)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void bootstrapWithUnmanagedThreads() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(UnmanagedThreadsBeanConfig.class);
|
||||
ctx.getBean("testBean1", TestBean.class);
|
||||
ctx.getBean("testBean2", TestBean.class);
|
||||
ctx.getBean("testBean3", TestBean.class);
|
||||
ctx.getBean("testBean4", TestBean.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@@ -55,6 +64,7 @@ class BackgroundBootstrapTests {
|
||||
ctx.getBean("testBean1", TestBean.class);
|
||||
ctx.getBean("testBean2", TestBean.class);
|
||||
ctx.getBean("testBean3", TestBean.class);
|
||||
ctx.getBean("testBean4", TestBean.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@@ -87,6 +97,45 @@ class BackgroundBootstrapTests {
|
||||
}
|
||||
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UnmanagedThreadsBeanConfig {
|
||||
|
||||
@Bean
|
||||
public TestBean testBean1(ObjectProvider<TestBean> testBean3, ObjectProvider<TestBean> testBean4) {
|
||||
new Thread(testBean3::getObject).start();
|
||||
new Thread(testBean4::getObject).start();
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean testBean2(TestBean testBean4) {
|
||||
return new TestBean(testBean4);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean testBean3(TestBean testBean4) {
|
||||
return new TestBean(testBean4);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean testBean4() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomExecutorBeanConfig {
|
||||
|
||||
@@ -117,8 +166,8 @@ class BackgroundBootstrapTests {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public String dependent(@Lazy TestBean testBean1, @Lazy TestBean testBean2, @Lazy TestBean testBean3) {
|
||||
return "";
|
||||
public TestBean testBean4(@Lazy TestBean testBean1, @Lazy TestBean testBean2, @Lazy TestBean testBean3) {
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user