From 341859b5fe5f93d0ff6b8355ea3a2ccc8d177e6e Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 11 Mar 2019 15:22:14 +0100 Subject: [PATCH] Start building against Spring Framework 5.2 snapshots See gh-16173 --- .../spring-boot-dependencies/pom.xml | 2 +- ...onConfigReactiveWebApplicationContext.java | 77 ++++++++++++- ...igReactiveWebServerApplicationContext.java | 100 ++++++++++++++++- ...figServletWebServerApplicationContext.java | 105 +++++++++++++++++- ...figReactiveWebApplicationContextTests.java | 86 ++++++++++++++ ...ctiveWebServerApplicationContextTests.java | 63 ++++++++++- ...rvletWebServerApplicationContextTests.java | 63 ++++++++++- 7 files changed, 490 insertions(+), 6 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContextTests.java diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index a926d6dcf67..d30397ceeca 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -177,7 +177,7 @@ 1.24 7.4.0 - 5.1.5.RELEASE + 5.2.0.BUILD-SNAPSHOT 2.1.4.RELEASE 4.1.1.RELEASE 2.0.4.RELEASE diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java index c93ee1b4752..81a36a570b4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -16,9 +16,11 @@ package org.springframework.boot.web.reactive.context; +import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Supplier; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.beans.factory.support.DefaultListableBeanFactory; @@ -65,6 +67,8 @@ public class AnnotationConfigReactiveWebApplicationContext private final Set basePackages = new LinkedHashSet<>(); + private final Set registeredBeans = new LinkedHashSet<>(); + @Override protected ConfigurableEnvironment createEnvironment() { return new StandardReactiveWebEnvironment(); @@ -139,6 +143,23 @@ public class AnnotationConfigReactiveWebApplicationContext this.annotatedClasses.addAll(Arrays.asList(annotatedClasses)); } + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, + Class... qualifiers) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, null, qualifiers)); + } + + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, Supplier supplier, + Class... qualifiers) { + this.registeredBeans + .add(new BeanRegistration(annotatedClass, supplier, qualifiers)); + } + /** * Perform a scan within the specified base packages. *

@@ -221,6 +242,9 @@ public class AnnotationConfigReactiveWebApplicationContext if (!this.basePackages.isEmpty()) { scanBasePackages(scanner); } + if (!this.registeredBeans.isEmpty()) { + registerBeans(reader); + } String[] configLocations = getConfigLocations(); if (configLocations != null) { registerConfigLocations(reader, scanner, configLocations); @@ -245,6 +269,16 @@ public class AnnotationConfigReactiveWebApplicationContext scanner.scan(StringUtils.toStringArray(this.basePackages)); } + private void registerBeans(AnnotatedBeanDefinitionReader reader) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Registering supplied beans: [" + + StringUtils.collectionToCommaDelimitedString(this.registeredBeans) + + "]"); + } + this.registeredBeans.forEach((reg) -> reader.registerBean(reg.getAnnotatedClass(), + reg.getSupplier(), reg.getQualifiers())); + } + private void registerConfigLocations(AnnotatedBeanDefinitionReader reader, ClassPathBeanDefinitionScanner scanner, String[] configLocations) throws LinkageError { @@ -323,4 +357,45 @@ public class AnnotationConfigReactiveWebApplicationContext return new FilteredReactiveWebContextResource(path); } + /** + * Holder for a programmatic bean registration. + * + * @see #registerBean(Class, Class[]) + * @see #registerBean(Class, Supplier, Class[]) + */ + private static class BeanRegistration { + + private final Class annotatedClass; + + private final Supplier supplier; + + private final Class[] qualifiers; + + BeanRegistration(Class annotatedClass, Supplier supplier, + Class[] qualifiers) { + this.annotatedClass = annotatedClass; + this.supplier = supplier; + this.qualifiers = qualifiers; + } + + public Class getAnnotatedClass() { + return this.annotatedClass; + } + + @SuppressWarnings("rawtypes") + public Supplier getSupplier() { + return this.supplier; + } + + public Class[] getQualifiers() { + return this.qualifiers; + } + + @Override + public String toString() { + return this.annotatedClass.getName(); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java index 37e1925a6f3..73f590d4ace 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -16,9 +16,11 @@ package org.springframework.boot.web.reactive.context; +import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Supplier; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanNameGenerator; @@ -35,6 +37,7 @@ import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; /** * {@link ReactiveWebServerApplicationContext} that accepts annotated classes as input - @@ -67,6 +70,8 @@ public class AnnotationConfigReactiveWebServerApplicationContext private String[] basePackages; + private final Set registeredBeans = new LinkedHashSet<>(); + /** * Create a new {@link AnnotationConfigReactiveWebServerApplicationContext} that needs * to be populated through {@link #register} calls and then manually @@ -197,6 +202,45 @@ public class AnnotationConfigReactiveWebServerApplicationContext this.basePackages = basePackages; } + /** + * Register a bean from the given bean class. + * @param annotatedClass the class of the bean + * @param the type of the bean + * @since 2.2.0 + */ + public final void registerBean(Class annotatedClass) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, null, null)); + } + + /** + * Register a bean from the given bean class, using the given supplier for obtaining a + * new instance (typically declared as a lambda expression or method reference). + * @param annotatedClass the class of the bean + * @param supplier a callback for creating an instance of the bean + * @param the type of the bean + * @since 2.2.0 + */ + public final void registerBean(Class annotatedClass, Supplier supplier) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, supplier, null)); + } + + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, + Class... qualifiers) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, null, qualifiers)); + } + + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, Supplier supplier, + Class... qualifiers) { + this.registeredBeans + .add(new BeanRegistration(annotatedClass, supplier, qualifiers)); + } + @Override protected void prepareRefresh() { this.scanner.clearCache(); @@ -212,6 +256,60 @@ public class AnnotationConfigReactiveWebServerApplicationContext if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } + if (!this.registeredBeans.isEmpty()) { + registerBeans(this.reader); + } + } + + private void registerBeans(AnnotatedBeanDefinitionReader reader) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Registering supplied beans: [" + + StringUtils.collectionToCommaDelimitedString(this.registeredBeans) + + "]"); + } + this.registeredBeans.forEach((reg) -> reader.registerBean(reg.getAnnotatedClass(), + reg.getSupplier(), reg.getQualifiers())); + } + + /** + * Holder for a programmatic bean registration. + * + * @see #registerBean(Class, Class[]) + * @see #registerBean(Class, Supplier, Class[]) + */ + private static class BeanRegistration { + + private final Class annotatedClass; + + private final Supplier supplier; + + private final Class[] qualifiers; + + BeanRegistration(Class annotatedClass, Supplier supplier, + Class[] qualifiers) { + this.annotatedClass = annotatedClass; + this.supplier = supplier; + this.qualifiers = qualifiers; + } + + public Class getAnnotatedClass() { + return this.annotatedClass; + } + + @SuppressWarnings("rawtypes") + public Supplier getSupplier() { + return this.supplier; + } + + public Class[] getQualifiers() { + return this.qualifiers; + } + + @Override + public String toString() { + return this.annotatedClass.getName(); + } + } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java index 11b65333260..4bdc0ff6367 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -16,9 +16,14 @@ package org.springframework.boot.web.servlet.context; +import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; +import java.util.function.Supplier; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanNameGenerator; @@ -33,6 +38,7 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.StringUtils; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; /** @@ -56,6 +62,8 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry { + private final Log logger = LogFactory.getLog(getClass()); + private final AnnotatedBeanDefinitionReader reader; private final ClassPathBeanDefinitionScanner scanner; @@ -64,6 +72,8 @@ public class AnnotationConfigServletWebServerApplicationContext private String[] basePackages; + private final Set registeredBeans = new LinkedHashSet<>(); + /** * Create a new {@link AnnotationConfigServletWebServerApplicationContext} that needs * to be populated through {@link #register} calls and then manually @@ -194,6 +204,45 @@ public class AnnotationConfigServletWebServerApplicationContext this.basePackages = basePackages; } + /** + * Register a bean from the given bean class. + * @param annotatedClass the class of the bean + * @param the type of the bean + * @since 2.2.0 + */ + public final void registerBean(Class annotatedClass) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, null, null)); + } + + /** + * Register a bean from the given bean class, using the given supplier for obtaining a + * new instance (typically declared as a lambda expression or method reference). + * @param annotatedClass the class of the bean + * @param supplier a callback for creating an instance of the bean + * @param the type of the bean + * @since 2.2.0 + */ + public final void registerBean(Class annotatedClass, Supplier supplier) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, supplier, null)); + } + + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, + Class... qualifiers) { + this.registeredBeans.add(new BeanRegistration(annotatedClass, null, qualifiers)); + } + + @Override + @SafeVarargs + @SuppressWarnings("varargs") + public final void registerBean(Class annotatedClass, Supplier supplier, + Class... qualifiers) { + this.registeredBeans + .add(new BeanRegistration(annotatedClass, supplier, qualifiers)); + } + @Override protected void prepareRefresh() { this.scanner.clearCache(); @@ -209,6 +258,60 @@ public class AnnotationConfigServletWebServerApplicationContext if (!this.annotatedClasses.isEmpty()) { this.reader.register(ClassUtils.toClassArray(this.annotatedClasses)); } + if (!this.registeredBeans.isEmpty()) { + registerBeans(this.reader); + } + } + + private void registerBeans(AnnotatedBeanDefinitionReader reader) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Registering supplied beans: [" + + StringUtils.collectionToCommaDelimitedString(this.registeredBeans) + + "]"); + } + this.registeredBeans.forEach((reg) -> reader.registerBean(reg.getAnnotatedClass(), + reg.getSupplier(), reg.getQualifiers())); + } + + /** + * Holder for a programmatic bean registration. + * + * @see #registerBean(Class, Class[]) + * @see #registerBean(Class, Supplier, Class[]) + */ + private static class BeanRegistration { + + private final Class annotatedClass; + + private final Supplier supplier; + + private final Class[] qualifiers; + + BeanRegistration(Class annotatedClass, Supplier supplier, + Class[] qualifiers) { + this.annotatedClass = annotatedClass; + this.supplier = supplier; + this.qualifiers = qualifiers; + } + + public Class getAnnotatedClass() { + return this.annotatedClass; + } + + @SuppressWarnings("rawtypes") + public Supplier getSupplier() { + return this.supplier; + } + + public Class[] getQualifiers() { + return this.qualifiers; + } + + @Override + public String toString() { + return this.annotatedClass.getName(); + } + } } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContextTests.java new file mode 100644 index 00000000000..ac00fef4afe --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContextTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2019 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.web.reactive.context; + +import org.junit.After; +import org.junit.Test; + +import org.springframework.context.annotation.Lazy; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AnnotationConfigReactiveWebApplicationContext} + * + * @author Stephane Nicoll + */ +public class AnnotationConfigReactiveWebApplicationContextTests { + + private AnnotationConfigReactiveWebApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void registerBean() { + this.context = new AnnotationConfigReactiveWebApplicationContext(); + this.context.registerBean(TestBean.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebApplicationContextTests.TestBean")).isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithLazy() { + this.context = new AnnotationConfigReactiveWebApplicationContext(); + this.context.registerBean(TestBean.class, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebApplicationContextTests.TestBean")).isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplier() { + this.context = new AnnotationConfigReactiveWebApplicationContext(); + this.context.registerBean(TestBean.class, TestBean::new); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebApplicationContextTests.TestBean")).isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplierAndLazy() { + this.context = new AnnotationConfigReactiveWebApplicationContext(); + this.context.registerBean(TestBean.class, TestBean::new, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebApplicationContextTests.TestBean")).isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + private static class TestBean { + + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java index 1656687cc1a..c3ed2f6d41a 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebServerApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -16,6 +16,7 @@ package org.springframework.boot.web.reactive.context; +import org.junit.After; import org.junit.Test; import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.ServerManager; @@ -25,6 +26,7 @@ import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.context.event.ApplicationEventMulticaster; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.SimpleApplicationEventMulticaster; @@ -42,6 +44,13 @@ public class AnnotationConfigReactiveWebServerApplicationContextTests { private AnnotationConfigReactiveWebServerApplicationContext context; + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + @Test public void createFromScan() { this.context = new AnnotationConfigReactiveWebServerApplicationContext( @@ -93,6 +102,54 @@ public class AnnotationConfigReactiveWebServerApplicationContextTests { verifyContext(); } + @Test + public void registerBean() { + this.context = new AnnotationConfigReactiveWebServerApplicationContext(); + this.context.register(ExampleReactiveWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebServerApplicationContextTests.TestBean")) + .isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithLazy() { + this.context = new AnnotationConfigReactiveWebServerApplicationContext(); + this.context.register(ExampleReactiveWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebServerApplicationContextTests.TestBean")) + .isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplier() { + this.context = new AnnotationConfigReactiveWebServerApplicationContext(); + this.context.register(ExampleReactiveWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, TestBean::new); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebServerApplicationContextTests.TestBean")) + .isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplierAndLazy() { + this.context = new AnnotationConfigReactiveWebServerApplicationContext(); + this.context.register(ExampleReactiveWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, TestBean::new, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigReactiveWebServerApplicationContextTests.TestBean")) + .isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + private void verifyContext() { MockReactiveWebServerFactory factory = this.context .getBean(MockReactiveWebServerFactory.class); @@ -174,4 +231,8 @@ public class AnnotationConfigReactiveWebServerApplicationContextTests { } + private static class TestBean { + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java index e8a0a0bcef2..f02f9b2cae5 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/context/AnnotationConfigServletWebServerApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -22,6 +22,7 @@ import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import org.junit.After; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +32,7 @@ import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.stereotype.Component; @@ -49,6 +51,13 @@ public class AnnotationConfigServletWebServerApplicationContextTests { private AnnotationConfigServletWebServerApplicationContext context; + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + @Test public void createFromScan() { this.context = new AnnotationConfigServletWebServerApplicationContext( @@ -133,6 +142,54 @@ public class AnnotationConfigServletWebServerApplicationContextTests { .getServletContext()).isNotNull(); } + @Test + public void registerBean() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(ExampleServletWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigServletWebServerApplicationContextTests.TestBean")) + .isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithLazy() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(ExampleServletWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigServletWebServerApplicationContextTests.TestBean")) + .isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplier() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(ExampleServletWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, TestBean::new); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigServletWebServerApplicationContextTests.TestBean")) + .isTrue(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + + @Test + public void registerBeanWithSupplierAndLazy() { + this.context = new AnnotationConfigServletWebServerApplicationContext(); + this.context.register(ExampleServletWebServerApplicationConfiguration.class); + this.context.registerBean(TestBean.class, TestBean::new, Lazy.class); + this.context.refresh(); + assertThat(this.context.getBeanFactory().containsSingleton( + "annotationConfigServletWebServerApplicationContextTests.TestBean")) + .isFalse(); + assertThat(this.context.getBean(TestBean.class)).isNotNull(); + } + private void verifyContext() { MockServletWebServerFactory factory = this.context .getBean(MockServletWebServerFactory.class); @@ -220,4 +277,8 @@ public class AnnotationConfigServletWebServerApplicationContextTests { } + private static class TestBean { + + } + }