diff --git a/spring-test/src/main/java/org/springframework/test/context/ApplicationContextFailureProcessor.java b/spring-test/src/main/java/org/springframework/test/context/ApplicationContextFailureProcessor.java index a947cbbfdd..c001d0b601 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ApplicationContextFailureProcessor.java +++ b/spring-test/src/main/java/org/springframework/test/context/ApplicationContextFailureProcessor.java @@ -22,6 +22,10 @@ import org.springframework.context.ApplicationContext; * Strategy for components that process failures related to application contexts * within the Spring TestContext Framework. * + *

Implementations must be registered via the + * {@link org.springframework.core.io.support.SpringFactoriesLoader SpringFactoriesLoader} + * mechanism. + * * @author Sam Brannen * @since 6.0 * @see ContextLoadException @@ -32,9 +36,10 @@ public interface ApplicationContextFailureProcessor { * Invoked when a failure was encountered while attempting to load an * {@link ApplicationContext}. *

Implementations of this method must not throw any exceptions. Consequently, - * any exception thrown by an implementation of this method will be ignored. + * any exception thrown by an implementation of this method will be ignored, though + * potentially logged. * @param context the application context that did not load successfully - * @param exception the exception caught while loading the application context + * @param exception the exception thrown while loading the application context */ void processLoadFailure(ApplicationContext context, Throwable exception); diff --git a/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java b/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java index 57ab6d7019..580b8fa2ff 100644 --- a/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java +++ b/spring-test/src/main/java/org/springframework/test/context/CacheAwareContextLoaderDelegate.java @@ -66,6 +66,12 @@ public interface CacheAwareContextLoaderDelegate { * configured in the given {@code MergedContextConfiguration}. *

If the context is present in the {@code ContextCache} it will simply * be returned; otherwise, it will be loaded, stored in the cache, and returned. + *

As of Spring Framework 6.0, implementations of this method should load + * {@link ApplicationContextFailureProcessor} implementations via the + * {@link org.springframework.core.io.support.SpringFactoriesLoader SpringFactoriesLoader} + * mechanism, catch any exception thrown by the {@link ContextLoader}, and + * delegate to each of the configured failure processors to process the context + * load failure if the thrown exception is an instance of {@link ContextLoadException}. *

The cache statistics should be logged by invoking * {@link org.springframework.test.context.cache.ContextCache#logStatistics()}. * @param mergedContextConfiguration the merged context configuration to use diff --git a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java index f0a94eb71d..0e1d421381 100644 --- a/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java +++ b/spring-test/src/main/java/org/springframework/test/context/cache/DefaultCacheAwareContextLoaderDelegate.java @@ -61,14 +61,15 @@ public class DefaultCacheAwareContextLoaderDelegate implements CacheAwareContext private static final Log logger = LogFactory.getLog(DefaultCacheAwareContextLoaderDelegate.class); - private static List contextFailureProcessors = - getApplicationContextFailureProcessors(); /** * Default static cache of Spring application contexts. */ static final ContextCache defaultContextCache = new DefaultContextCache(); + private List contextFailureProcessors = + loadApplicationContextFailureProcessors(); + private final AotTestContextInitializers aotTestContextInitializers = new AotTestContextInitializers(); private final ContextCache contextCache; @@ -127,7 +128,7 @@ public class DefaultCacheAwareContextLoaderDelegate implements CacheAwareContext Throwable cause = ex; if (ex instanceof ContextLoadException cle) { cause = cle.getCause(); - for (ApplicationContextFailureProcessor contextFailureProcessor : contextFailureProcessors) { + for (ApplicationContextFailureProcessor contextFailureProcessor : this.contextFailureProcessors) { try { contextFailureProcessor.processLoadFailure(cle.getApplicationContext(), cause); } @@ -259,7 +260,7 @@ public class DefaultCacheAwareContextLoaderDelegate implements CacheAwareContext * @return the context failure processors to use * @since 6.0 */ - private static List getApplicationContextFailureProcessors() { + private static List loadApplicationContextFailureProcessors() { SpringFactoriesLoader loader = SpringFactoriesLoader.forDefaultResourceLocation( DefaultCacheAwareContextLoaderDelegate.class.getClassLoader()); List processors = loader.load(ApplicationContextFailureProcessor.class,