25
25
import org .junit .jupiter .api .Test ;
26
26
27
27
import org .springframework .beans .BeanWrapper ;
28
- import org .springframework .beans .factory .BeanCreationException ;
29
28
import org .springframework .beans .factory .FactoryBean ;
30
29
import org .springframework .beans .factory .annotation .Qualifier ;
31
30
import org .springframework .beans .factory .config .BeanDefinition ;
43
42
import org .springframework .util .Assert ;
44
43
45
44
import static org .assertj .core .api .Assertions .assertThat ;
46
- import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
47
45
import static org .assertj .core .api .Assertions .assertThatIllegalStateException ;
48
46
import static org .assertj .core .api .Assertions .assertThatNoException ;
49
47
import static org .mockito .Mockito .mock ;
@@ -228,17 +226,15 @@ void replaceBeanByNameWithMatchingBeanDefinitionForClassBasedSingletonFactoryBea
228
226
}
229
227
230
228
@ Test
231
- void replaceBeanByNameWithMatchingBeanDefinitionForClassBasedNonSingletonFactoryBean () {
229
+ void replaceBeanByNameWithMatchingBeanDefinitionForClassBasedNonSingletonFactoryBeanFails () {
232
230
String beanName = "descriptionBean" ;
233
231
AnnotationConfigApplicationContext context = createContext (CaseByName .class );
234
232
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition (NonSingletonStringFactoryBean .class );
235
233
context .registerBeanDefinition (beanName , factoryBeanDefinition );
236
234
237
- assertThatNoException ().isThrownBy (context ::refresh );
238
- // Even though the FactoryBean signals it does not manage a singleton,
239
- // the Bean Override support currently replaces it with a singleton.
240
- assertThat (context .isSingleton (beanName )).as ("isSingleton" ).isTrue ();
241
- assertThat (context .getBean (beanName )).isEqualTo ("overridden" );
235
+ assertThatIllegalStateException ()
236
+ .isThrownBy (context ::refresh )
237
+ .withMessage ("Unable to override bean 'descriptionBean': only singleton beans can be overridden." );
242
238
}
243
239
244
240
@ Test
@@ -254,44 +250,33 @@ void replaceBeanByNameWithMatchingBeanDefinitionForInterfaceBasedSingletonFactor
254
250
}
255
251
256
252
@ Test
257
- void replaceBeanByNameWithMatchingBeanDefinitionForInterfaceBasedNonSingletonFactoryBean () {
253
+ void replaceBeanByNameWithMatchingBeanDefinitionForInterfaceBasedNonSingletonFactoryBeanFails () {
258
254
String beanName = "messageServiceBean" ;
259
255
AnnotationConfigApplicationContext context = createContext (MessageServiceTestCase .class );
260
256
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition (NonSingletonMessageServiceFactoryBean .class );
261
257
context .registerBeanDefinition (beanName , factoryBeanDefinition );
262
258
263
- assertThatNoException ().isThrownBy (context ::refresh );
264
- // Even though the FactoryBean signals it does not manage a singleton,
265
- // the Bean Override support currently replaces it with a singleton.
266
- assertThat (context .isSingleton (beanName )).as ("isSingleton" ).isTrue ();
267
- assertThat (context .getBean (beanName , MessageService .class ).getMessage ()).isEqualTo ("overridden" );
259
+ assertThatIllegalStateException ()
260
+ .isThrownBy (context ::refresh )
261
+ .withMessage ("Unable to override bean 'messageServiceBean': only singleton beans can be overridden." );
268
262
}
269
263
270
264
@ Test
271
- void replaceBeanByNameWithMatchingBeanDefinitionWithPrototypeScope () {
265
+ void replaceBeanByNameWithMatchingBeanDefinitionWithPrototypeScopeFails () {
272
266
String beanName = "descriptionBean" ;
273
267
274
268
AnnotationConfigApplicationContext context = createContext (CaseByName .class );
275
269
RootBeanDefinition definition = new RootBeanDefinition (String .class , () -> "ORIGINAL" );
276
270
definition .setScope (BeanDefinition .SCOPE_PROTOTYPE );
277
271
context .registerBeanDefinition (beanName , definition );
278
272
279
- assertThatNoException ().isThrownBy (context ::refresh );
280
- // The Bean Override support currently creates a "dummy" BeanDefinition that
281
- // retains the prototype scope of the original BeanDefinition.
282
- assertThat (context .isSingleton (beanName )).as ("isSingleton" ).isFalse ();
283
- assertThat (context .isPrototype (beanName )).as ("isPrototype" ).isTrue ();
284
- // Since the "dummy" BeanDefinition has prototype scope, a manual singleton
285
- // is not registered, and the "dummy" BeanDefinition is used to create a
286
- // new java.lang.String using the default constructor, which results in an
287
- // empty string instead of "overridden". In other words, the bean is not
288
- // actually overridden as expected, and no exception is thrown which
289
- // silently masks the issue.
290
- assertThat (context .getBean (beanName )).isEqualTo ("" );
273
+ assertThatIllegalStateException ()
274
+ .isThrownBy (context ::refresh )
275
+ .withMessage ("Unable to override bean 'descriptionBean': only singleton beans can be overridden." );
291
276
}
292
277
293
278
@ Test
294
- void replaceBeanByNameWithMatchingBeanDefinitionWithCustomScope () {
279
+ void replaceBeanByNameWithMatchingBeanDefinitionWithCustomScopeFails () {
295
280
String beanName = "descriptionBean" ;
296
281
String scope = "customScope" ;
297
282
@@ -302,49 +287,28 @@ void replaceBeanByNameWithMatchingBeanDefinitionWithCustomScope() {
302
287
definition .setScope (scope );
303
288
context .registerBeanDefinition (beanName , definition );
304
289
305
- assertThatNoException ().isThrownBy (context ::refresh );
306
- // The Bean Override support currently creates a "dummy" BeanDefinition that
307
- // retains the custom scope of the original BeanDefinition.
308
- assertThat (context .isSingleton (beanName )).as ("isSingleton" ).isFalse ();
309
- assertThat (context .isPrototype (beanName )).as ("isPrototype" ).isFalse ();
310
- assertThat (beanFactory .getBeanDefinition (beanName ).getScope ()).isEqualTo (scope );
311
- // Since the "dummy" BeanDefinition has a custom scope, a manual singleton
312
- // is not registered, and the "dummy" BeanDefinition is used to create a
313
- // new java.lang.String using the default constructor, which results in an
314
- // empty string instead of "overridden". In other words, the bean is not
315
- // actually overridden as expected, and no exception is thrown which
316
- // silently masks the issue.
317
- assertThat (context .getBean (beanName )).isEqualTo ("" );
290
+ assertThatIllegalStateException ()
291
+ .isThrownBy (context ::refresh )
292
+ .withMessage ("Unable to override bean 'descriptionBean': only singleton beans can be overridden." );
318
293
}
319
294
320
295
@ Test
321
- void replaceBeanByNameWithMatchingBeanDefinitionForPrototypeScopedFactoryBean () {
296
+ void replaceBeanByNameWithMatchingBeanDefinitionForPrototypeScopedFactoryBeanFails () {
322
297
String beanName = "messageServiceBean" ;
323
298
AnnotationConfigApplicationContext context = createContext (MessageServiceTestCase .class );
324
299
RootBeanDefinition factoryBeanDefinition = new RootBeanDefinition (SingletonMessageServiceFactoryBean .class );
325
300
factoryBeanDefinition .setScope (BeanDefinition .SCOPE_PROTOTYPE );
326
301
context .registerBeanDefinition (beanName , factoryBeanDefinition );
327
302
328
- assertThatNoException ().isThrownBy (context ::refresh );
329
- // The Bean Override support currently creates a "dummy" BeanDefinition that
330
- // retains the prototype scope of the original BeanDefinition.
331
- assertThat (context .isSingleton (beanName )).as ("isSingleton" ).isFalse ();
332
- assertThat (context .isPrototype (beanName )).as ("isPrototype" ).isTrue ();
333
- // Since the "dummy" BeanDefinition has prototype scope, a manual singleton
334
- // is not registered, and the "dummy" BeanDefinition is used to create a
335
- // new MessageService using the default constructor, which results in an
336
- // error since MessageService is an interface.
337
- assertThatExceptionOfType (BeanCreationException .class )
338
- .isThrownBy (() -> context .getBean (beanName ))
339
- .withMessageContaining ("Specified class is an interface" );
303
+ assertThatIllegalStateException ()
304
+ .isThrownBy (context ::refresh )
305
+ .withMessage ("Unable to override bean 'messageServiceBean': only singleton beans can be overridden." );
340
306
}
341
307
342
308
@ Test
343
- void replaceBeanByNameWithMatchingBeanDefinitionRetainsPrimaryFallbackAndScopeProperties () {
309
+ void replaceBeanByNameWithMatchingBeanDefinitionRetainsPrimaryAndFallbackFlags () {
344
310
AnnotationConfigApplicationContext context = createContext (CaseByName .class );
345
- context .getBeanFactory ().registerScope ("customScope" , new SimpleThreadScope ());
346
311
RootBeanDefinition definition = new RootBeanDefinition (String .class , () -> "ORIGINAL" );
347
- definition .setScope ("customScope" );
348
312
definition .setPrimary (true );
349
313
definition .setFallback (true );
350
314
context .registerBeanDefinition ("descriptionBean" , definition );
@@ -354,8 +318,8 @@ void replaceBeanByNameWithMatchingBeanDefinitionRetainsPrimaryFallbackAndScopePr
354
318
.isNotSameAs (definition )
355
319
.matches (BeanDefinition ::isPrimary , "isPrimary" )
356
320
.matches (BeanDefinition ::isFallback , "isFallback" )
357
- .satisfies (d -> assertThat (d .getScope ()).isEqualTo ("customScope " ))
358
- .matches (Predicate . not ( BeanDefinition ::isSingleton ) , "! isSingleton" )
321
+ .satisfies (d -> assertThat (d .getScope ()).isEqualTo ("" ))
322
+ .matches (BeanDefinition ::isSingleton , "isSingleton" )
359
323
.matches (Predicate .not (BeanDefinition ::isPrototype ), "!isPrototype" );
360
324
}
361
325
0 commit comments