1919import org .junit .jupiter .api .Test ;
2020import org .junit .jupiter .api .Timeout ;
2121
22- import org .springframework .beans .factory .BeanCurrentlyInCreationException ;
2322import org .springframework .beans .factory .ObjectProvider ;
2423import org .springframework .beans .testfixture .beans .TestBean ;
2524import org .springframework .context .ConfigurableApplicationContext ;
2625import org .springframework .core .testfixture .EnabledForTestGroups ;
2726import org .springframework .scheduling .concurrent .ThreadPoolTaskExecutor ;
2827
29- import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
3028import static org .springframework .context .annotation .Bean .Bootstrap .BACKGROUND ;
3129import static org .springframework .core .testfixture .TestGroup .LONG_RUNNING ;
3230
@@ -42,8 +40,19 @@ class BackgroundBootstrapTests {
4240 void bootstrapWithUnmanagedThread () {
4341 ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext (UnmanagedThreadBeanConfig .class );
4442 ctx .getBean ("testBean1" , TestBean .class );
45- assertThatExceptionOfType (BeanCurrentlyInCreationException .class ).isThrownBy ( // late - not during refresh
46- () -> ctx .getBean ("testBean2" , TestBean .class ));
43+ ctx .getBean ("testBean2" , TestBean .class );
44+ ctx .close ();
45+ }
46+
47+ @ Test
48+ @ Timeout (5 )
49+ @ EnabledForTestGroups (LONG_RUNNING )
50+ void bootstrapWithUnmanagedThreads () {
51+ ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext (UnmanagedThreadsBeanConfig .class );
52+ ctx .getBean ("testBean1" , TestBean .class );
53+ ctx .getBean ("testBean2" , TestBean .class );
54+ ctx .getBean ("testBean3" , TestBean .class );
55+ ctx .getBean ("testBean4" , TestBean .class );
4756 ctx .close ();
4857 }
4958
@@ -55,6 +64,7 @@ void bootstrapWithCustomExecutor() {
5564 ctx .getBean ("testBean1" , TestBean .class );
5665 ctx .getBean ("testBean2" , TestBean .class );
5766 ctx .getBean ("testBean3" , TestBean .class );
67+ ctx .getBean ("testBean4" , TestBean .class );
5868 ctx .close ();
5969 }
6070
@@ -87,6 +97,45 @@ public TestBean testBean2() {
8797 }
8898
8999
100+ @ Configuration (proxyBeanMethods = false )
101+ static class UnmanagedThreadsBeanConfig {
102+
103+ @ Bean
104+ public TestBean testBean1 (ObjectProvider <TestBean > testBean3 , ObjectProvider <TestBean > testBean4 ) {
105+ new Thread (testBean3 ::getObject ).start ();
106+ new Thread (testBean4 ::getObject ).start ();
107+ try {
108+ Thread .sleep (1000 );
109+ }
110+ catch (InterruptedException ex ) {
111+ throw new RuntimeException (ex );
112+ }
113+ return new TestBean ();
114+ }
115+
116+ @ Bean
117+ public TestBean testBean2 (TestBean testBean4 ) {
118+ return new TestBean (testBean4 );
119+ }
120+
121+ @ Bean
122+ public TestBean testBean3 (TestBean testBean4 ) {
123+ return new TestBean (testBean4 );
124+ }
125+
126+ @ Bean
127+ public TestBean testBean4 () {
128+ try {
129+ Thread .sleep (2000 );
130+ }
131+ catch (InterruptedException ex ) {
132+ throw new RuntimeException (ex );
133+ }
134+ return new TestBean ();
135+ }
136+ }
137+
138+
90139 @ Configuration (proxyBeanMethods = false )
91140 static class CustomExecutorBeanConfig {
92141
@@ -117,8 +166,8 @@ public TestBean testBean3() {
117166 }
118167
119168 @ Bean
120- public String dependent (@ Lazy TestBean testBean1 , @ Lazy TestBean testBean2 , @ Lazy TestBean testBean3 ) {
121- return "" ;
169+ public TestBean testBean4 (@ Lazy TestBean testBean1 , @ Lazy TestBean testBean2 , @ Lazy TestBean testBean3 ) {
170+ return new TestBean () ;
122171 }
123172 }
124173
0 commit comments