@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2012 - 2020 the original author or authors .
* Copyright 2012 - 2021 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 .
@ -105,31 +105,49 @@ import org.springframework.util.Assert;
@@ -105,31 +105,49 @@ import org.springframework.util.Assert;
* /
public abstract class AbstractApplicationContextRunner < SELF extends AbstractApplicationContextRunner < SELF , C , A > , C extends ConfigurableApplicationContext , A extends ApplicationContextAssertProvider < C > > {
private final Supplier < C > contextFactory ;
private final boolean allowBeanDefinitionOverriding ;
private final List < ApplicationContextInitializer < ? super C > > initializers ;
private final TestPropertyValues environmentProperties ;
private final TestPropertyValues systemProperties ;
private final RunnerConfiguration < C > runnerConfiguration ;
private final ClassLoader classLoader ;
private final ApplicationContext parent ;
private final List < BeanRegistration < ? > > beanRegistrations ;
private final List < Configurations > configurations ;
private final Function < RunnerConfiguration < C > , SELF > instanceFactory ;
/ * *
* Create a new { @link AbstractApplicationContextRunner } instance .
* @param contextFactory the factory used to create the actual context
* @deprecated since 2 . 6 . 0 for removal in 2 . 8 . 0 in favor of
* { @link # AbstractApplicationContextRunner ( Supplier , Function ) }
* /
@Deprecated
protected AbstractApplicationContextRunner ( Supplier < C > contextFactory ) {
this ( contextFactory , false , Collections . emptyList ( ) , TestPropertyValues . empty ( ) , TestPropertyValues . empty ( ) ,
null , null , Collections . emptyList ( ) , Collections . emptyList ( ) ) ;
Assert . notNull ( contextFactory , "ContextFactory must not be null" ) ;
this . runnerConfiguration = new RunnerConfiguration < > ( contextFactory ) ;
this . instanceFactory = this : : legacyNewInstance ;
}
/ * *
* Create a new { @link AbstractApplicationContextRunner } instance .
* @param contextFactory the factory used to create the actual context
* @param instanceFactory the factory used to create new instance of the runner
* @since 2 . 6 . 0
* /
protected AbstractApplicationContextRunner ( Supplier < C > contextFactory ,
Function < RunnerConfiguration < C > , SELF > instanceFactory ) {
Assert . notNull ( contextFactory , "ContextFactory must not be null" ) ;
Assert . notNull ( contextFactory , "RunnerConfiguration must not be null" ) ;
this . runnerConfiguration = new RunnerConfiguration < > ( contextFactory ) ;
this . instanceFactory = instanceFactory ;
}
/ * *
* Create a new { @link AbstractApplicationContextRunner } instance .
* @param configuration the configuration for the runner to use
* @param instanceFactory the factory used to create new instance of the runner
* @since 2 . 6 . 0
* /
protected AbstractApplicationContextRunner ( RunnerConfiguration < C > configuration ,
Function < RunnerConfiguration < C > , SELF > instanceFactory ) {
Assert . notNull ( configuration , "RunnerConfiguration must not be null" ) ;
Assert . notNull ( instanceFactory , "instanceFactory must not be null" ) ;
this . runnerConfiguration = configuration ;
this . instanceFactory = instanceFactory ;
}
/ * *
@ -143,7 +161,10 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -143,7 +161,10 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @param parent the parent
* @param beanRegistrations the bean registrations
* @param configurations the configuration
* @deprecated since 2 . 6 . 0 for removal in 2 . 8 . 0 in favor of
* { @link # AbstractApplicationContextRunner ( Supplier , Function ) }
* /
@Deprecated
protected AbstractApplicationContextRunner ( Supplier < C > contextFactory , boolean allowBeanDefinitionOverriding ,
List < ApplicationContextInitializer < ? super C > > initializers , TestPropertyValues environmentProperties ,
TestPropertyValues systemProperties , ClassLoader classLoader , ApplicationContext parent ,
@ -153,15 +174,17 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -153,15 +174,17 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
Assert . notNull ( systemProperties , "SystemProperties must not be null" ) ;
Assert . notNull ( configurations , "Configurations must not be null" ) ;
Assert . notNull ( initializers , "Initializers must not be null" ) ;
this . contextFactory = contextFactory ;
this . allowBeanDefinitionOverriding = allowBeanDefinitionOverriding ;
this . initializers = Collections . unmodifiableList ( initializers ) ;
this . environmentProperties = environmentProperties ;
this . systemProperties = systemProperties ;
this . classLoader = classLoader ;
this . parent = parent ;
this . beanRegistrations = Collections . unmodifiableList ( beanRegistrations ) ;
this . configurations = Collections . unmodifiableList ( configurations ) ;
RunnerConfiguration < C > configuration = new RunnerConfiguration < > ( contextFactory ) ;
configuration . allowBeanDefinitionOverriding = allowBeanDefinitionOverriding ;
configuration . initializers = Collections . unmodifiableList ( initializers ) ;
configuration . environmentProperties = environmentProperties ;
configuration . systemProperties = systemProperties ;
configuration . classLoader = classLoader ;
configuration . parent = parent ;
configuration . beanRegistrations = Collections . unmodifiableList ( beanRegistrations ) ;
configuration . configurations = Collections . unmodifiableList ( configurations ) ;
this . runnerConfiguration = configuration ;
this . instanceFactory = this : : legacyNewInstance ;
}
/ * *
@ -173,9 +196,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -173,9 +196,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @see DefaultListableBeanFactory # setAllowBeanDefinitionOverriding ( boolean )
* /
public SELF withAllowBeanDefinitionOverriding ( boolean allowBeanDefinitionOverriding ) {
return newInstance ( this . contextFactory , allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , this . classLoader , this . parent ,
this . beanRegistrations , this . configurations ) ;
return newInstance ( this . runnerConfiguration . withAllowBeanDefinitionOverriding ( allowBeanDefinitionOverriding ) ) ;
}
/ * *
@ -186,9 +207,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -186,9 +207,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* /
public SELF withInitializer ( ApplicationContextInitializer < ? super C > initializer ) {
Assert . notNull ( initializer , "Initializer must not be null" ) ;
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , add ( this . initializers , initializer ) ,
this . environmentProperties , this . systemProperties , this . classLoader , this . parent ,
this . beanRegistrations , this . configurations ) ;
return newInstance ( this . runnerConfiguration . withInitializer ( initializer ) ) ;
}
/ * *
@ -202,9 +221,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -202,9 +221,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @see # withSystemProperties ( String . . . )
* /
public SELF withPropertyValues ( String . . . pairs ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties . and ( pairs ) , this . systemProperties , this . classLoader , this . parent ,
this . beanRegistrations , this . configurations ) ;
return newInstance ( this . runnerConfiguration . withPropertyValues ( pairs ) ) ;
}
/ * *
@ -218,9 +235,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -218,9 +235,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @see # withSystemProperties ( String . . . )
* /
public SELF withSystemProperties ( String . . . pairs ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties . and ( pairs ) , this . classLoader , this . parent ,
this . beanRegistrations , this . configurations ) ;
return newInstance ( this . runnerConfiguration . withSystemProperties ( pairs ) ) ;
}
/ * *
@ -231,9 +246,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -231,9 +246,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @see FilteredClassLoader
* /
public SELF withClassLoader ( ClassLoader classLoader ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , classLoader , this . parent , this . beanRegistrations ,
this . configurations ) ;
return newInstance ( this . runnerConfiguration . withClassLoader ( classLoader ) ) ;
}
/ * *
@ -243,9 +256,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -243,9 +256,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @return a new instance with the updated parent
* /
public SELF withParent ( ApplicationContext parent ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , this . classLoader , parent , this . beanRegistrations ,
this . configurations ) ;
return newInstance ( this . runnerConfiguration . withParent ( parent ) ) ;
}
/ * *
@ -280,9 +291,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -280,9 +291,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* @return a new instance with the updated bean
* /
public < T > SELF withBean ( String name , Class < T > type , Object . . . constructorArgs ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , this . classLoader , this . parent ,
add ( this . beanRegistrations , new BeanRegistration < > ( name , type , constructorArgs ) ) , this . configurations ) ;
return newInstance ( this . runnerConfiguration . withBean ( name , type , constructorArgs ) ) ;
}
/ * *
@ -320,10 +329,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -320,10 +329,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* /
public < T > SELF withBean ( String name , Class < T > type , Supplier < T > supplier ,
BeanDefinitionCustomizer . . . customizers ) {
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , this . classLoader , this . parent ,
add ( this . beanRegistrations , new BeanRegistration < > ( name , type , supplier , customizers ) ) ,
this . configurations ) ;
return newInstance ( this . runnerConfiguration . withBean ( name , type , supplier , customizers ) ) ;
}
/ * *
@ -343,9 +349,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -343,9 +349,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* /
public SELF withConfiguration ( Configurations configurations ) {
Assert . notNull ( configurations , "Configurations must not be null" ) ;
return newInstance ( this . contextFactory , this . allowBeanDefinitionOverriding , this . initializers ,
this . environmentProperties , this . systemProperties , this . classLoader , this . parent ,
this . beanRegistrations , add ( this . configurations , configurations ) ) ;
return newInstance ( this . runnerConfiguration . withConfiguration ( configurations ) ) ;
}
/ * *
@ -358,17 +362,24 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -358,17 +362,24 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
return customizer . apply ( ( SELF ) this ) ;
}
private < T > List < T > add ( List < T > list , T element ) {
List < T > result = new ArrayList < > ( list ) ;
result . add ( element ) ;
return result ;
@Deprecated
private SELF legacyNewInstance ( RunnerConfiguration < C > configuration ) {
return newInstance ( configuration . contextFactory , configuration . allowBeanDefinitionOverriding ,
configuration . initializers , configuration . environmentProperties , configuration . systemProperties ,
configuration . classLoader , configuration . parent , configuration . beanRegistrations ,
configuration . configurations ) ;
}
@Deprecated
protected abstract SELF newInstance ( Supplier < C > contextFactory , boolean allowBeanDefinitionOverriding ,
List < ApplicationContextInitializer < ? super C > > initializers , TestPropertyValues environmentProperties ,
TestPropertyValues systemProperties , ClassLoader classLoader , ApplicationContext parent ,
List < BeanRegistration < ? > > beanRegistrations , List < Configurations > configurations ) ;
private SELF newInstance ( RunnerConfiguration < C > runnerConfiguration ) {
return this . instanceFactory . apply ( runnerConfiguration ) ;
}
/ * *
* Create and refresh a new { @link ApplicationContext } based on the current state of
* this loader . The context is consumed by the specified { @code consumer } and closed
@ -378,7 +389,8 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -378,7 +389,8 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
* /
@SuppressWarnings ( "unchecked" )
public SELF run ( ContextConsumer < ? super A > consumer ) {
withContextClassLoader ( this . classLoader , ( ) - > this . systemProperties . applyToSystemProperties ( ( ) - > {
withContextClassLoader ( this . runnerConfiguration . classLoader ,
( ) - > this . runnerConfiguration . systemProperties . applyToSystemProperties ( ( ) - > {
try ( A context = createAssertableContext ( ) ) {
accept ( consumer , context ) ;
}
@ -413,11 +425,11 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -413,11 +425,11 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
}
private C createAndLoadContext ( ) {
C context = this . contextFactory . get ( ) ;
C context = this . runnerConfiguration . contextFactory . get ( ) ;
ConfigurableListableBeanFactory beanFactory = context . getBeanFactory ( ) ;
if ( beanFactory instanceof DefaultListableBeanFactory ) {
( ( DefaultListableBeanFactory ) beanFactory )
. setAllowBeanDefinitionOverriding ( this . allowBeanDefinitionOverriding ) ;
. setAllowBeanDefinitionOverriding ( this . runnerConfiguration . allowBeanDefinitionOverriding ) ;
}
try {
configureContext ( context ) ;
@ -430,20 +442,20 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -430,20 +442,20 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
}
private void configureContext ( C context ) {
if ( this . parent ! = null ) {
context . setParent ( this . parent ) ;
if ( this . runnerConfiguration . parent ! = null ) {
context . setParent ( this . runnerConfiguration . parent ) ;
}
if ( this . classLoader ! = null ) {
if ( this . runnerConfiguration . classLoader ! = null ) {
Assert . isInstanceOf ( DefaultResourceLoader . class , context ) ;
( ( DefaultResourceLoader ) context ) . setClassLoader ( this . classLoader ) ;
( ( DefaultResourceLoader ) context ) . setClassLoader ( this . runnerConfiguration . classLoader ) ;
}
this . environmentProperties . applyTo ( context ) ;
Class < ? > [ ] classes = Configurations . getClasses ( this . configurations ) ;
this . runnerConfiguration . environmentProperties . applyTo ( context ) ;
Class < ? > [ ] classes = Configurations . getClasses ( this . runnerConfiguration . configurations ) ;
if ( classes . length > 0 ) {
( ( AnnotationConfigRegistry ) context ) . register ( classes ) ;
}
this . beanRegistrations . forEach ( ( registration ) - > registration . apply ( context ) ) ;
this . initializers . forEach ( ( initializer ) - > initializer . initialize ( context ) ) ;
this . runnerConfiguration . beanRegistrations . forEach ( ( registration ) - > registration . apply ( context ) ) ;
this . runnerConfiguration . initializers . forEach ( ( initializer ) - > initializer . initialize ( context ) ) ;
context . refresh ( ) ;
}
@ -466,7 +478,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -466,7 +478,7 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
*
* @param < T > the bean type
* /
protected final class BeanRegistration < T > {
protected static final class BeanRegistration < T > {
Consumer < GenericApplicationContext > registrar ;
@ -486,4 +498,107 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
@@ -486,4 +498,107 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
}
protected static final class RunnerConfiguration < C extends ConfigurableApplicationContext > {
private final Supplier < C > contextFactory ;
private boolean allowBeanDefinitionOverriding = false ;
private List < ApplicationContextInitializer < ? super C > > initializers = Collections . emptyList ( ) ;
private TestPropertyValues environmentProperties = TestPropertyValues . empty ( ) ;
private TestPropertyValues systemProperties = TestPropertyValues . empty ( ) ;
private ClassLoader classLoader ;
private ApplicationContext parent ;
private List < BeanRegistration < ? > > beanRegistrations = Collections . emptyList ( ) ;
private List < Configurations > configurations = Collections . emptyList ( ) ;
private RunnerConfiguration ( Supplier < C > contextFactory ) {
this . contextFactory = contextFactory ;
}
private RunnerConfiguration ( RunnerConfiguration < C > source ) {
this . contextFactory = source . contextFactory ;
this . allowBeanDefinitionOverriding = source . allowBeanDefinitionOverriding ;
this . initializers = source . initializers ;
this . environmentProperties = source . environmentProperties ;
this . systemProperties = source . systemProperties ;
this . classLoader = source . classLoader ;
this . parent = source . parent ;
this . beanRegistrations = source . beanRegistrations ;
this . configurations = source . configurations ;
}
private RunnerConfiguration < C > withAllowBeanDefinitionOverriding ( boolean allowBeanDefinitionOverriding ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . allowBeanDefinitionOverriding = allowBeanDefinitionOverriding ;
return config ;
}
private RunnerConfiguration < C > withInitializer ( ApplicationContextInitializer < ? super C > initializer ) {
Assert . notNull ( initializer , "Initializer must not be null" ) ;
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . initializers = add ( config . initializers , initializer ) ;
return config ;
}
private RunnerConfiguration < C > withPropertyValues ( String . . . pairs ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . environmentProperties = config . environmentProperties . and ( pairs ) ;
return config ;
}
private RunnerConfiguration < C > withSystemProperties ( String . . . pairs ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . systemProperties = config . systemProperties . and ( pairs ) ;
return config ;
}
private RunnerConfiguration < C > withClassLoader ( ClassLoader classLoader ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . classLoader = classLoader ;
return config ;
}
private RunnerConfiguration < C > withParent ( ApplicationContext parent ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . parent = parent ;
return config ;
}
private < T > RunnerConfiguration < C > withBean ( String name , Class < T > type , Object . . . constructorArgs ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . beanRegistrations = add ( config . beanRegistrations ,
new BeanRegistration < > ( name , type , constructorArgs ) ) ;
return config ;
}
private < T > RunnerConfiguration < C > withBean ( String name , Class < T > type , Supplier < T > supplier ,
BeanDefinitionCustomizer . . . customizers ) {
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . beanRegistrations = add ( config . beanRegistrations ,
new BeanRegistration < > ( name , type , supplier , customizers ) ) ;
return config ;
}
private RunnerConfiguration < C > withConfiguration ( Configurations configurations ) {
Assert . notNull ( configurations , "Configurations must not be null" ) ;
RunnerConfiguration < C > config = new RunnerConfiguration < > ( this ) ;
config . configurations = add ( config . configurations , configurations ) ;
return config ;
}
private static < T > List < T > add ( List < T > list , T element ) {
List < T > result = new ArrayList < > ( list ) ;
result . add ( element ) ;
return result ;
}
}
}