Merge branch '5.3.x'
# Conflicts: # spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java # spring-context/src/test/java/org/springframework/context/support/GenericApplicationContextTests.java
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
@@ -31,90 +32,100 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.FileSystemResourceLoader;
|
||||
import org.springframework.core.io.FileUrlResource;
|
||||
import org.springframework.core.io.ProtocolResolver;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.metrics.jfr.FlightRecorderApplicationStartup;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.type;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link GenericApplicationContext}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class GenericApplicationContextTests {
|
||||
|
||||
private final GenericApplicationContext context = new GenericApplicationContext();
|
||||
|
||||
@AfterEach
|
||||
void closeContext() {
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getBeanForClass() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
ac.registerBeanDefinition("testBean", new RootBeanDefinition(String.class));
|
||||
ac.refresh();
|
||||
context.registerBeanDefinition("testBean", new RootBeanDefinition(String.class));
|
||||
context.refresh();
|
||||
|
||||
assertThat(ac.getBean("testBean")).isEqualTo("");
|
||||
assertThat(ac.getBean(String.class)).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean(CharSequence.class)).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(context.getBean("testBean")).isEqualTo("");
|
||||
assertThat(context.getBean(String.class)).isSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getBean(CharSequence.class)).isSameAs(context.getBean("testBean"));
|
||||
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class).isThrownBy(() ->
|
||||
ac.getBean(Object.class));
|
||||
ac.close();
|
||||
assertThatExceptionOfType(NoUniqueBeanDefinitionException.class)
|
||||
.isThrownBy(() -> context.getBean(Object.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withSingletonSupplier() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
ac.registerBeanDefinition("testBean", new RootBeanDefinition(String.class, ac::toString));
|
||||
ac.refresh();
|
||||
context.registerBeanDefinition("testBean", new RootBeanDefinition(String.class, context::toString));
|
||||
context.refresh();
|
||||
|
||||
assertThat(ac.getBean("testBean")).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean(String.class)).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean(CharSequence.class)).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean("testBean")).isEqualTo(ac.toString());
|
||||
ac.close();
|
||||
assertThat(context.getBean("testBean")).isSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getBean(String.class)).isSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getBean(CharSequence.class)).isSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getBean("testBean")).isEqualTo(context.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void withScopedSupplier() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
ac.registerBeanDefinition("testBean",
|
||||
new RootBeanDefinition(String.class, BeanDefinition.SCOPE_PROTOTYPE, ac::toString));
|
||||
ac.refresh();
|
||||
context.registerBeanDefinition("testBean",
|
||||
new RootBeanDefinition(String.class, BeanDefinition.SCOPE_PROTOTYPE, context::toString));
|
||||
context.refresh();
|
||||
|
||||
assertThat(ac.getBean("testBean")).isNotSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean(String.class)).isEqualTo(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean(CharSequence.class)).isEqualTo(ac.getBean("testBean"));
|
||||
assertThat(ac.getBean("testBean")).isEqualTo(ac.toString());
|
||||
ac.close();
|
||||
assertThat(context.getBean("testBean")).isNotSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getBean(String.class)).isEqualTo(context.getBean("testBean"));
|
||||
assertThat(context.getBean(CharSequence.class)).isEqualTo(context.getBean("testBean"));
|
||||
assertThat(context.getBean("testBean")).isEqualTo(context.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void accessAfterClosing() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
ac.registerBeanDefinition("testBean", new RootBeanDefinition(String.class));
|
||||
ac.refresh();
|
||||
context.registerBeanDefinition("testBean", new RootBeanDefinition(String.class));
|
||||
context.refresh();
|
||||
|
||||
assertThat(ac.getBean(String.class)).isSameAs(ac.getBean("testBean"));
|
||||
assertThat(ac.getAutowireCapableBeanFactory().getBean(String.class)).isSameAs(ac.getAutowireCapableBeanFactory().getBean("testBean"));
|
||||
assertThat(context.getBean(String.class)).isSameAs(context.getBean("testBean"));
|
||||
assertThat(context.getAutowireCapableBeanFactory().getBean(String.class))
|
||||
.isSameAs(context.getAutowireCapableBeanFactory().getBean("testBean"));
|
||||
|
||||
ac.close();
|
||||
context.close();
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
ac.getBean(String.class));
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() -> {
|
||||
ac.getAutowireCapableBeanFactory().getBean("testBean");
|
||||
ac.getAutowireCapableBeanFactory().getBean(String.class);
|
||||
});
|
||||
ac.close();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> context.getBean(String.class));
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> context.getAutowireCapableBeanFactory().getBean(String.class));
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> context.getAutowireCapableBeanFactory().getBean("testBean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualBeans() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class);
|
||||
context.registerBean(BeanB.class);
|
||||
context.registerBean(BeanC.class);
|
||||
@@ -123,12 +134,10 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean(BeanA.class).b).isSameAs(context.getBean(BeanB.class));
|
||||
assertThat(context.getBean(BeanA.class).c).isSameAs(context.getBean(BeanC.class));
|
||||
assertThat(context.getBean(BeanB.class).applicationContext).isSameAs(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualNamedBeans() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class);
|
||||
context.registerBean("b", BeanB.class);
|
||||
context.registerBean("c", BeanC.class);
|
||||
@@ -137,12 +146,10 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean("a", BeanA.class).b).isSameAs(context.getBean("b"));
|
||||
assertThat(context.getBean("a", BeanA.class).c).isSameAs(context.getBean("c"));
|
||||
assertThat(context.getBean("b", BeanB.class).applicationContext).isSameAs(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualBeanWithSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
|
||||
context.registerBean(BeanB.class, BeanB::new);
|
||||
@@ -154,14 +161,14 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean(BeanA.class).c).isSameAs(context.getBean(BeanC.class));
|
||||
assertThat(context.getBean(BeanB.class).applicationContext).isSameAs(context);
|
||||
|
||||
assertThat(context.getDefaultListableBeanFactory().getDependentBeans(BeanB.class.getName())).isEqualTo(new String[] {BeanA.class.getName()});
|
||||
assertThat(context.getDefaultListableBeanFactory().getDependentBeans(BeanC.class.getName())).isEqualTo(new String[] {BeanA.class.getName()});
|
||||
context.close();
|
||||
assertThat(context.getDefaultListableBeanFactory().getDependentBeans(BeanB.class.getName()))
|
||||
.containsExactly(BeanA.class.getName());
|
||||
assertThat(context.getDefaultListableBeanFactory().getDependentBeans(BeanC.class.getName()))
|
||||
.containsExactly(BeanA.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualBeanWithSupplierAndCustomizer() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean(BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)),
|
||||
bd -> bd.setLazyInit(true));
|
||||
@@ -173,12 +180,10 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean(BeanA.class).b).isSameAs(context.getBean(BeanB.class));
|
||||
assertThat(context.getBean(BeanA.class).c).isSameAs(context.getBean(BeanC.class));
|
||||
assertThat(context.getBean(BeanB.class).applicationContext).isSameAs(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualNamedBeanWithSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)));
|
||||
context.registerBean("b", BeanB.class, BeanB::new);
|
||||
@@ -189,12 +194,10 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean(BeanA.class).b).isSameAs(context.getBean("b", BeanB.class));
|
||||
assertThat(context.getBean("a", BeanA.class).c).isSameAs(context.getBean("c"));
|
||||
assertThat(context.getBean("b", BeanB.class).applicationContext).isSameAs(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualNamedBeanWithSupplierAndCustomizer() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class,
|
||||
() -> new BeanA(context.getBean(BeanB.class), context.getBean(BeanC.class)),
|
||||
bd -> bd.setLazyInit(true));
|
||||
@@ -206,33 +209,63 @@ class GenericApplicationContextTests {
|
||||
assertThat(context.getBean(BeanA.class).b).isSameAs(context.getBean("b", BeanB.class));
|
||||
assertThat(context.getBean("a", BeanA.class).c).isSameAs(context.getBean("c"));
|
||||
assertThat(context.getBean("b", BeanB.class).applicationContext).isSameAs(context);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void individualBeanWithNullReturningSupplier() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.registerBean("a", BeanA.class, () -> null);
|
||||
context.registerBean("b", BeanB.class, BeanB::new);
|
||||
context.registerBean("c", BeanC.class, BeanC::new);
|
||||
context.refresh();
|
||||
|
||||
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanA.class), "a")).isTrue();
|
||||
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanB.class), "b")).isTrue();
|
||||
assertThat(ObjectUtils.containsElement(context.getBeanNamesForType(BeanC.class), "c")).isTrue();
|
||||
assertThat(context.getBeansOfType(BeanA.class).isEmpty()).isTrue();
|
||||
assertThat(context.getBeansOfType(BeanB.class).values().iterator().next()).isSameAs(context.getBean(BeanB.class));
|
||||
assertThat(context.getBeansOfType(BeanC.class).values().iterator().next()).isSameAs(context.getBean(BeanC.class));
|
||||
context.close();
|
||||
assertThat(context.getBeanNamesForType(BeanA.class)).containsExactly("a");
|
||||
assertThat(context.getBeanNamesForType(BeanB.class)).containsExactly("b");
|
||||
assertThat(context.getBeanNamesForType(BeanC.class)).containsExactly("c");
|
||||
assertThat(context.getBeansOfType(BeanA.class)).isEmpty();
|
||||
assertThat(context.getBeansOfType(BeanB.class).values().iterator().next())
|
||||
.isSameAs(context.getBean(BeanB.class));
|
||||
assertThat(context.getBeansOfType(BeanC.class).values().iterator().next())
|
||||
.isSameAs(context.getBean(BeanC.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void configureApplicationStartupOnBeanFactory() {
|
||||
FlightRecorderApplicationStartup applicationStartup = new FlightRecorderApplicationStartup();
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
context.setApplicationStartup(applicationStartup);
|
||||
assertThat(context.getBeanFactory().getApplicationStartup()).isEqualTo(applicationStartup);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getResourceWithDefaultResourceLoader() {
|
||||
assertGetResourceSemantics(null, ClassPathResource.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getResourceWithCustomResourceLoader() {
|
||||
assertGetResourceSemantics(new FileSystemResourceLoader(), FileSystemResource.class);
|
||||
}
|
||||
|
||||
private void assertGetResourceSemantics(ResourceLoader resourceLoader, Class<? extends Resource> defaultResouceType) {
|
||||
if (resourceLoader != null) {
|
||||
context.setResourceLoader(resourceLoader);
|
||||
}
|
||||
|
||||
String pingLocation = "ping:foo";
|
||||
String fileLocation = "file:foo";
|
||||
|
||||
Resource resource = context.getResource(pingLocation);
|
||||
assertThat(resource).isInstanceOf(defaultResouceType);
|
||||
resource = context.getResource(fileLocation);
|
||||
assertThat(resource).isInstanceOf(FileUrlResource.class);
|
||||
|
||||
context.addProtocolResolver(new PingPongProtocolResolver());
|
||||
|
||||
resource = context.getResource(pingLocation);
|
||||
assertThat(resource).asInstanceOf(type(ByteArrayResource.class))
|
||||
.extracting(bar -> new String(bar.getByteArray(), UTF_8))
|
||||
.isEqualTo("pong:foo");
|
||||
resource = context.getResource(fileLocation);
|
||||
assertThat(resource).isInstanceOf(FileUrlResource.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -455,4 +488,15 @@ class GenericApplicationContextTests {
|
||||
}
|
||||
}
|
||||
|
||||
static class PingPongProtocolResolver implements ProtocolResolver {
|
||||
|
||||
@Override
|
||||
public Resource resolve(String location, ResourceLoader resourceLoader) {
|
||||
if (location.startsWith("ping:")) {
|
||||
return new ByteArrayResource(("pong:" + location.substring(5)).getBytes(UTF_8));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user