Commit e306aad2 authored by Andy Wilkinson's avatar Andy Wilkinson

Merge branch '2.0.x'

parents 68c10ea0 27267a70
......@@ -196,9 +196,8 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
}
/**
* Customize the {@link ClassLoader} that the {@link ApplicationContext} should use.
* Customizing the {@link ClassLoader} is an effective manner to hide resources from
* the classpath.
* Customize the {@link ClassLoader} that the {@link ApplicationContext} should use
* for resource loading and bean class loading.
* @param classLoader the classloader to use (can be null to use the default)
* @return a new instance with the updated class loader
* @see FilteredClassLoader
......@@ -274,15 +273,34 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
*/
@SuppressWarnings("unchecked")
public SELF run(ContextConsumer<? super A> consumer) {
this.systemProperties.applyToSystemProperties(() -> {
try (A context = createAssertableContext()) {
accept(consumer, context);
}
return null;
withContextClassLoader(this.classLoader, () -> {
this.systemProperties.applyToSystemProperties(() -> {
try (A context = createAssertableContext()) {
accept(consumer, context);
}
return null;
});
});
return (SELF) this;
}
private void withContextClassLoader(ClassLoader classLoader, Runnable action) {
if (classLoader == null) {
action.run();
}
else {
Thread currentThread = Thread.currentThread();
ClassLoader previous = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(classLoader);
try {
action.run();
}
finally {
currentThread.setContextClassLoader(previous);
}
}
}
@SuppressWarnings("unchecked")
private A createAssertableContext() {
ResolvableType resolvableType = ResolvableType
......
......@@ -30,8 +30,12 @@ import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.assertj.ApplicationContextAssertProvider;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
import static org.assertj.core.api.Assertions.assertThat;
......@@ -150,7 +154,7 @@ public abstract class AbstractApplicationContextRunnerTests<T extends AbstractAp
}
@Test
public void runWithClassLoaderShouldSetClassLoader() {
public void runWithClassLoaderShouldSetClassLoaderOnContext() {
get().withClassLoader(new FilteredClassLoader(Gson.class.getPackage().getName()))
.run((context) -> {
try {
......@@ -164,6 +168,14 @@ public abstract class AbstractApplicationContextRunnerTests<T extends AbstractAp
});
}
@Test
public void runWithClassLoaderShouldSetClassLoaderOnConditionContext() {
get().withClassLoader(new FilteredClassLoader(Gson.class.getPackage().getName()))
.withUserConfiguration(ConditionalConfig.class)
.run((context) -> assertThat(context)
.hasSingleBean(ConditionalConfig.class));
}
@Test
public void thrownRuleWorksWithCheckedException() {
get().run((context) -> {
......@@ -209,4 +221,19 @@ public abstract class AbstractApplicationContextRunnerTests<T extends AbstractAp
}
@Configuration
@Conditional(FilteredClassLoaderCondition.class)
static class ConditionalConfig {
}
static class FilteredClassLoaderCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getClassLoader() instanceof FilteredClassLoader;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment