Apply initializers and bean registrations before registering classes

Previously, classes were registered first which meant that their
conditions were evaluated before any initializers and bean
registrations were applied. This prevented the bean registrations and
initializers from affecting the outcome of the condition evaluation.

This commit inverts the ordering so that classes are not registerd,
and therefore their conditions are not evaluated, until after the
bean registrations and initializers have been applied.

Closes gh-31280
pull/31304/head
Andy Wilkinson 2 years ago
parent e30391ca7a
commit 62f40f2c38

@ -402,12 +402,12 @@ public abstract class AbstractApplicationContextRunner<SELF extends AbstractAppl
((DefaultResourceLoader) context).setClassLoader(this.runnerConfiguration.classLoader); ((DefaultResourceLoader) context).setClassLoader(this.runnerConfiguration.classLoader);
} }
this.runnerConfiguration.environmentProperties.applyTo(context); this.runnerConfiguration.environmentProperties.applyTo(context);
this.runnerConfiguration.beanRegistrations.forEach((registration) -> registration.apply(context));
this.runnerConfiguration.initializers.forEach((initializer) -> initializer.initialize(context));
Class<?>[] classes = Configurations.getClasses(this.runnerConfiguration.configurations); Class<?>[] classes = Configurations.getClasses(this.runnerConfiguration.configurations);
if (classes.length > 0) { if (classes.length > 0) {
((AnnotationConfigRegistry) context).register(classes); ((AnnotationConfigRegistry) context).register(classes);
} }
this.runnerConfiguration.beanRegistrations.forEach((registration) -> registration.apply(context));
this.runnerConfiguration.initializers.forEach((initializer) -> initializer.initialize(context));
context.refresh(); context.refresh();
} }

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -39,6 +39,7 @@ import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata; import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -230,6 +231,13 @@ abstract class AbstractApplicationContextRunnerTests<T extends AbstractApplicati
}); });
} }
@Test
void changesMadeByInitializersShouldBeVisibleToRegisteredClasses() {
get().withInitializer((context) -> context.getEnvironment().setActiveProfiles("test"))
.withUserConfiguration(ProfileConfig.class)
.run((context) -> assertThat(context).hasSingleBean(ProfileConfig.class));
}
protected abstract T get(); protected abstract T get();
private static void throwCheckedException(String message) throws IOException { private static void throwCheckedException(String message) throws IOException {
@ -342,4 +350,10 @@ abstract class AbstractApplicationContextRunnerTests<T extends AbstractApplicati
} }
@Profile("test")
@Configuration(proxyBeanMethods = false)
static class ProfileConfig {
}
} }

Loading…
Cancel
Save