Migrate ApplicationContext to common hierarchy

This commit migrates `AnnotationConfigReactiveWebApplicationContext`
parent to the `GenericApplicationContext` abstraction. Any use of
`AnnotationConfigWebApplicationContext` is also removed as it also
inherits from the `AbstractRefreshableApplicationContext` outdated
hierarchy.

A new `AnnotationConfigServletWebApplicationContext` context is
introduced instead, extending from `GenericApplicationContext` and
providing the counter part of the reactive context for the Servlet-based
web app tests.

See gh-16096
This commit is contained in:
Stephane Nicoll 2019-04-02 10:06:33 +02:00
parent 4bcc632850
commit c432288ed1
24 changed files with 303 additions and 353 deletions

View File

@ -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.
@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockServletContext;
@ -45,7 +46,6 @@ import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@ -60,7 +60,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
public class ControllerEndpointWebMvcIntegrationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -70,7 +70,7 @@ public class ControllerEndpointWebMvcIntegrationTests {
@Test
public void endpointsAreSecureByDefault() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class, ExampleController.class);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/actuator/example").accept(MediaType.APPLICATION_JSON))
@ -81,7 +81,7 @@ public class ControllerEndpointWebMvcIntegrationTests {
public void endpointsCanBeAccessed() throws Exception {
TestSecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class, ExampleController.class);
TestPropertyValues
.of("management.endpoints.web.base-path:/management",

View File

@ -30,12 +30,12 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
@ -49,11 +49,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
public class WebMvcEndpointCorsIntegrationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@Before
public void createContext() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,

View File

@ -43,6 +43,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -54,7 +55,6 @@ import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.hasKey;
@ -70,7 +70,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
public class WebMvcEndpointIntegrationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -80,7 +80,7 @@ public class WebMvcEndpointIntegrationTests {
@Test
public void endpointsAreSecureByDefault() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/actuator/beans").accept(MediaType.APPLICATION_JSON))
@ -89,7 +89,7 @@ public class WebMvcEndpointIntegrationTests {
@Test
public void endpointsAreSecureByDefaultWithCustomBasePath() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class);
TestPropertyValues.of("management.endpoints.web.base-path:/management")
.applyTo(this.context);
@ -102,7 +102,7 @@ public class WebMvcEndpointIntegrationTests {
public void endpointsAreSecureWithActuatorRoleWithCustomBasePath() throws Exception {
TestSecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class);
TestPropertyValues
.of("management.endpoints.web.base-path:/management",
@ -114,7 +114,7 @@ public class WebMvcEndpointIntegrationTests {
@Test
public void linksAreProvidedToAllEndpointTypes() throws Exception {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class);
TestPropertyValues.of("management.endpoints.web.exposure.include=*")
.applyTo(this.context);

View File

@ -42,6 +42,7 @@ import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDesc
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -50,7 +51,6 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
@ -133,7 +133,7 @@ public class MappingsEndpointTests {
given((Map<String, ServletRegistration>) servletContext.getServletRegistrations())
.willReturn(Collections.singletonMap("testServlet", servletRegistration));
return () -> {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
context.setServletContext(servletContext);
return context;
};

View File

@ -24,13 +24,13 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
@ -54,7 +54,7 @@ public class ConditionalOnWebApplicationTests {
@Test
public void testWebApplicationWithServletContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext ctx = new AnnotationConfigServletWebApplicationContext();
ctx.register(AnyWebApplicationConfiguration.class,
ServletWebApplicationConfiguration.class,
ReactiveWebApplicationConfiguration.class);

View File

@ -26,11 +26,11 @@ import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
@ -43,7 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class JpaWebAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -52,7 +52,7 @@ public class JpaWebAutoConfigurationTests {
@Test
public void testDefaultRepositoryConfiguration() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(TestConfiguration.class,
EmbeddedDataSourceConfiguration.class,

View File

@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -41,7 +42,6 @@ import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguratio
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
@ -55,7 +55,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class RepositoryRestMvcAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void tearDown() {
@ -143,7 +143,7 @@ public class RepositoryRestMvcAutoConfigurationTests {
}
private void load(Class<?> config, String... environment) {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext applicationContext = new AnnotationConfigServletWebApplicationContext();
applicationContext.setServletContext(new MockServletContext());
applicationContext.register(config, BaseConfiguration.class);
TestPropertyValues.of(environment).applyTo(applicationContext);

View File

@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -38,7 +39,6 @@ import org.springframework.context.annotation.Import;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter;
import org.springframework.web.servlet.support.RequestContext;
@ -57,7 +57,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class FreeMarkerAutoConfigurationServletIntegrationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -206,7 +206,7 @@ public class FreeMarkerAutoConfigurationServletIntegrationTests {
}
private void load(Class<?> config, String... env) {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
TestPropertyValues.of(env).applyTo(this.context);
this.context.register(config);

View File

@ -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.
@ -32,12 +32,12 @@ import org.junit.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.support.RequestContext;
@ -56,7 +56,7 @@ public class GroovyTemplateAutoConfigurationTests {
private final BuildOutput buildOutput = new BuildOutput(getClass());
private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
private AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
@Before
public void setupContext() {

View File

@ -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.
@ -23,8 +23,8 @@ import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*/
public class H2ConsoleAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
private AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
@Before
public void setupContext() {

View File

@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConf
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.client.LinkDiscoverer;
@ -40,7 +41,6 @@ import org.springframework.hateoas.server.mvc.TypeConstrainedMappingJackson2Http
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import static org.assertj.core.api.Assertions.assertThat;
@ -54,7 +54,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class HypermediaAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -65,7 +65,7 @@ public class HypermediaAutoConfigurationTests {
@Test
public void linkDiscoverersCreated() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(BaseConfig.class);
this.context.refresh();
@ -78,7 +78,7 @@ public class HypermediaAutoConfigurationTests {
@Test
public void entityLinksCreated() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(BaseConfig.class);
this.context.refresh();
@ -88,7 +88,7 @@ public class HypermediaAutoConfigurationTests {
@Test
public void doesBackOffIfEnableHypermediaSupportIsDeclaredManually() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(EnableHypermediaSupportConfig.class, BaseConfig.class);
TestPropertyValues.of("spring.jackson.serialization.INDENT_OUTPUT:true")
@ -100,7 +100,7 @@ public class HypermediaAutoConfigurationTests {
@Test
public void supportedMediaTypesOfTypeConstrainedConvertersIsCustomized() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(BaseConfig.class);
this.context.refresh();
@ -116,7 +116,7 @@ public class HypermediaAutoConfigurationTests {
@Test
public void customizationOfSupportedMediaTypesCanBeDisabled() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(BaseConfig.class);
TestPropertyValues.of("spring.hateoas.use-hal-as-default-json-media-type:false")

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 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.
@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConf
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.testsupport.runner.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.runner.classpath.ModifiedClassPathRunner;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* Tests for {@link HypermediaAutoConfiguration} when Jackson is not on the classpath.
@ -36,11 +36,11 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
@ClassPathExclusions("jackson-*.jar")
public class HypermediaAutoConfigurationWithoutJacksonTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@Test
public void jacksonRelatedConfigurationBacksOff() {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(BaseConfig.class);
this.context.setServletContext(new MockServletContext());
this.context.refresh();

View File

@ -33,13 +33,13 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.logging.LogLevel;
import org.springframework.boot.testsupport.rule.OutputCapture;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -121,7 +121,7 @@ public class ConditionEvaluationReportLoggingListenerTests {
@Test
public void canBeUsedInNonGenericApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
context.setServletContext(new MockServletContext());
context.register(Config.class);
new ConditionEvaluationReportLoggingListener().initialize(context);

View File

@ -21,11 +21,11 @@ import org.junit.Test;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.view.MustacheViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@ -36,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class MustacheAutoConfigurationTests {
private AnnotationConfigWebApplicationContext webContext;
private AnnotationConfigServletWebApplicationContext webContext;
private AnnotationConfigReactiveWebApplicationContext reactiveWebContext;
@ -91,7 +91,7 @@ public class MustacheAutoConfigurationTests {
}
private void loadWithServlet(Class<?> config) {
this.webContext = new AnnotationConfigWebApplicationContext();
this.webContext = new AnnotationConfigServletWebApplicationContext();
TestPropertyValues.of("spring.mustache.prefix=classpath:/mustache-templates/")
.applyTo(this.webContext);
if (config != null) {

View File

@ -29,10 +29,10 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAut
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfigurationEarlyInitializationTests.JacksonModuleBean;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* Tests for {@link SecurityFilterAutoConfiguration}.
@ -43,7 +43,7 @@ public class SecurityFilterAutoConfigurationTests {
@Test
public void filterAutoConfigurationWorksWithoutSecurityAutoConfiguration() {
try (AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext()) {
try (AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext()) {
context.setServletContext(new MockServletContext());
context.register(Config.class);
context.refresh();

View File

@ -31,13 +31,13 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter;
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
@ -51,7 +51,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*/
public class HttpEncodingAutoConfigurationTests {
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
@After
public void close() {
@ -179,9 +179,9 @@ public class HttpEncodingAutoConfigurationTests {
this.context = doLoad(new Class<?>[] { config }, environment);
}
private AnnotationConfigWebApplicationContext doLoad(Class<?>[] configs,
private AnnotationConfigServletWebApplicationContext doLoad(Class<?>[] configs,
String... environment) {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext applicationContext = new AnnotationConfigServletWebApplicationContext();
TestPropertyValues.of(environment).applyTo(applicationContext);
applicationContext.register(configs);
applicationContext.register(MinimalWebAutoConfiguration.class,

View File

@ -28,6 +28,7 @@ import org.springframework.boot.devtools.restart.MockRestarter;
import org.springframework.boot.devtools.restart.server.HttpRestartServer;
import org.springframework.boot.devtools.restart.server.SourceFolderUrlFilter;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@ -37,7 +38,6 @@ import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -58,7 +58,7 @@ public class RemoteDevToolsAutoConfigurationTests {
@Rule
public MockRestarter mockRestarter = new MockRestarter();
private AnnotationConfigWebApplicationContext context;
private AnnotationConfigServletWebApplicationContext context;
private MockHttpServletRequest request;
@ -174,7 +174,7 @@ public class RemoteDevToolsAutoConfigurationTests {
}
private void loadContext(String... properties) {
this.context = new AnnotationConfigWebApplicationContext();
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.setServletContext(new MockServletContext());
this.context.register(Config.class, PropertyPlaceholderAutoConfiguration.class);
TestPropertyValues.of(properties).applyTo(this.context);

View File

@ -27,13 +27,13 @@ import javax.servlet.http.HttpServlet;
import org.junit.Test;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@ -49,7 +49,7 @@ public class SpringBootMockMvcBuilderCustomizerTests {
@Test
@SuppressWarnings("unchecked")
public void customizeShouldAddFilters() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
MockServletContext servletContext = new MockServletContext();
context.setServletContext(servletContext);
context.register(ServletConfiguration.class, FilterConfiguration.class);

View File

@ -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,12 +22,12 @@ import java.util.function.Supplier;
import org.springframework.boot.context.annotation.Configurations;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* An {@link AbstractApplicationContextRunner ApplicationContext runner} for a Servlet
@ -45,12 +45,12 @@ public final class WebApplicationContextRunner extends
/**
* Create a new {@link WebApplicationContextRunner} instance using an
* {@link AnnotationConfigWebApplicationContext} with a {@link MockServletContext} as
* the underlying source.
* {@link AnnotationConfigServletWebApplicationContext} with a
* {@link MockServletContext} as the underlying source.
* @see #withMockServletContext(Supplier)
*/
public WebApplicationContextRunner() {
this(withMockServletContext(AnnotationConfigWebApplicationContext::new));
this(withMockServletContext(AnnotationConfigServletWebApplicationContext::new));
}
/**

View File

@ -16,33 +16,19 @@
package org.springframework.boot.web.reactive.context;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigRegistry;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.context.support.AbstractRefreshableConfigApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* {@link ConfigurableReactiveWebApplicationContext} that accepts annotated classes as
* input - in particular
* {@link org.springframework.context.annotation.Configuration @Configuration}-annotated
* classes, but also plain {@link Component @Component} classes and JSR-330 compliant
* classes using {@code javax.inject} annotations. Allows for registering classes one by
* one (specifying class names as config location) as well as for classpath scanning
* (specifying base packages as config location).
* input - in particular {@link Configuration @Configuration}-annotated classes, but also
* plain {@link Component @Component} classes and JSR-330 compliant classes using
* {@code javax.inject} annotations. Allows for registering classes one by one (specifying
* class names as config location) as well as for classpath scanning (specifying base
* packages as config location).
* <p>
* Note: In case of multiple {@code @Configuration} classes, later {@code @Bean}
* definitions will override ones defined in earlier loaded files. This can be leveraged
@ -50,273 +36,17 @@ import org.springframework.util.StringUtils;
*
* @author Phillip Webb
* @since 2.0.0
* @see #register(Class...)
* @see #scan(String...)
* @see AnnotationConfigApplicationContext
*/
public class AnnotationConfigReactiveWebApplicationContext
extends AbstractRefreshableConfigApplicationContext
implements ConfigurableReactiveWebApplicationContext, AnnotationConfigRegistry {
private BeanNameGenerator beanNameGenerator;
private ScopeMetadataResolver scopeMetadataResolver;
private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();
private final Set<String> basePackages = new LinkedHashSet<>();
extends AnnotationConfigApplicationContext
implements ConfigurableReactiveWebApplicationContext {
@Override
protected ConfigurableEnvironment createEnvironment() {
return new StandardReactiveWebEnvironment();
}
/**
* Set a custom {@link BeanNameGenerator} for use with
* {@link AnnotatedBeanDefinitionReader} and/or
* {@link ClassPathBeanDefinitionScanner}.
* <p>
* Default is
* {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}.
* @param beanNameGenerator the bean name generator
* @see AnnotatedBeanDefinitionReader#setBeanNameGenerator
* @see ClassPathBeanDefinitionScanner#setBeanNameGenerator
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = beanNameGenerator;
}
/**
* Return the custom {@link BeanNameGenerator} for use with
* {@link AnnotatedBeanDefinitionReader} and/or
* {@link ClassPathBeanDefinitionScanner}, if any.
* @return the bean name generator
*/
protected BeanNameGenerator getBeanNameGenerator() {
return this.beanNameGenerator;
}
/**
* Set a custom {@link ScopeMetadataResolver} for use with
* {@link AnnotatedBeanDefinitionReader} and/or
* {@link ClassPathBeanDefinitionScanner}.
* <p>
* Default is an
* {@link org.springframework.context.annotation.AnnotationScopeMetadataResolver}.
* @param scopeMetadataResolver the scope metadata resolver
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
*/
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
this.scopeMetadataResolver = scopeMetadataResolver;
}
/**
* Return the custom {@link ScopeMetadataResolver} for use with
* {@link AnnotatedBeanDefinitionReader} and/or
* {@link ClassPathBeanDefinitionScanner}, if any.
* @return the scope metadata resolver
*/
protected ScopeMetadataResolver getScopeMetadataResolver() {
return this.scopeMetadataResolver;
}
/**
* Register one or more annotated classes to be processed.
* <p>
* Note that {@link #refresh()} must be called in order for the context to fully
* process the new classes.
* @param annotatedClasses one or more annotated classes, e.g.
* {@link org.springframework.context.annotation.Configuration @Configuration} classes
* @see #scan(String...)
* @see #loadBeanDefinitions(DefaultListableBeanFactory)
* @see #setConfigLocation(String)
* @see #refresh()
*/
@Override
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses,
"At least one annotated class must be specified");
this.annotatedClasses.addAll(Arrays.asList(annotatedClasses));
}
/**
* Perform a scan within the specified base packages.
* <p>
* Note that {@link #refresh()} must be called in order for the context to fully
* process the new classes.
* @param basePackages the packages to check for annotated classes
* @see #loadBeanDefinitions(DefaultListableBeanFactory)
* @see #register(Class...)
* @see #setConfigLocation(String)
* @see #refresh()
*/
@Override
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.basePackages.addAll(Arrays.asList(basePackages));
}
/**
* Register a {@link org.springframework.beans.factory.config.BeanDefinition} for any
* classes specified by {@link #register(Class...)} and scan any packages specified by
* {@link #scan(String...)}.
* <p>
* For any values specified by {@link #setConfigLocation(String)} or
* {@link #setConfigLocations(String[])}, attempt first to load each location as a
* class, registering a {@code BeanDefinition} if class loading is successful, and if
* class loading fails (i.e. a {@code ClassNotFoundException} is raised), assume the
* value is a package and attempt to scan it for annotated classes.
* <p>
* Enables the default set of annotation configuration post processors, such that
* {@code @Autowired}, {@code @Required}, and associated annotations can be used.
* <p>
* Configuration class bean definitions are registered with generated bean definition
* names unless the {@code value} attribute is provided to the stereotype annotation.
* @param beanFactory the bean factory to load bean definitions into
* @see #register(Class...)
* @see #scan(String...)
* @see #setConfigLocation(String)
* @see #setConfigLocations(String[])
* @see AnnotatedBeanDefinitionReader
* @see ClassPathBeanDefinitionScanner
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(
beanFactory);
ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(
beanFactory);
applyBeanNameGenerator(beanFactory, reader, scanner);
applyScopeMetadataResolver(reader, scanner);
loadBeanDefinitions(reader, scanner);
}
private void applyBeanNameGenerator(DefaultListableBeanFactory beanFactory,
AnnotatedBeanDefinitionReader reader,
ClassPathBeanDefinitionScanner scanner) {
BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
if (beanNameGenerator != null) {
reader.setBeanNameGenerator(beanNameGenerator);
scanner.setBeanNameGenerator(beanNameGenerator);
beanFactory.registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
beanNameGenerator);
}
}
private void applyScopeMetadataResolver(AnnotatedBeanDefinitionReader reader,
ClassPathBeanDefinitionScanner scanner) {
ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
if (scopeMetadataResolver != null) {
reader.setScopeMetadataResolver(scopeMetadataResolver);
scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
}
private void loadBeanDefinitions(AnnotatedBeanDefinitionReader reader,
ClassPathBeanDefinitionScanner scanner) throws LinkageError {
if (!this.annotatedClasses.isEmpty()) {
registerAnnotatedClasses(reader);
}
if (!this.basePackages.isEmpty()) {
scanBasePackages(scanner);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
registerConfigLocations(reader, scanner, configLocations);
}
}
private void registerAnnotatedClasses(AnnotatedBeanDefinitionReader reader) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Registering annotated classes: ["
+ StringUtils.collectionToCommaDelimitedString(this.annotatedClasses)
+ "]");
}
reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
private void scanBasePackages(ClassPathBeanDefinitionScanner scanner) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Scanning base packages: ["
+ StringUtils.collectionToCommaDelimitedString(this.basePackages)
+ "]");
}
scanner.scan(StringUtils.toStringArray(this.basePackages));
}
private void registerConfigLocations(AnnotatedBeanDefinitionReader reader,
ClassPathBeanDefinitionScanner scanner, String[] configLocations)
throws LinkageError {
for (String configLocation : configLocations) {
try {
register(reader, configLocation);
}
catch (ClassNotFoundException ex) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Could not load class for config location ["
+ configLocation + "] - trying package scan. " + ex);
}
int count = scanner.scan(configLocation);
if (this.logger.isInfoEnabled()) {
logScanResult(configLocation, count);
}
}
}
}
private void register(AnnotatedBeanDefinitionReader reader, String configLocation)
throws ClassNotFoundException, LinkageError {
Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
if (this.logger.isInfoEnabled()) {
this.logger.info("Successfully resolved class for [" + configLocation + "]");
}
reader.register(clazz);
}
private void logScanResult(String configLocation, int count) {
if (count == 0) {
this.logger.info("No annotated classes found for specified class/package ["
+ configLocation + "]");
}
else {
this.logger.info("Found " + count + " annotated classes in package ["
+ configLocation + "]");
}
}
/**
* Build an {@link AnnotatedBeanDefinitionReader} for the given bean factory.
* <p>
* This should be pre-configured with the {@code Environment} (if desired) but not
* with a {@code BeanNameGenerator} or {@code ScopeMetadataResolver} yet.
* @param beanFactory the bean factory to load bean definitions into
* @return the annotated bean definition reader
* @see #getEnvironment()
* @see #getBeanNameGenerator()
* @see #getScopeMetadataResolver()
*/
protected AnnotatedBeanDefinitionReader getAnnotatedBeanDefinitionReader(
DefaultListableBeanFactory beanFactory) {
return new AnnotatedBeanDefinitionReader(beanFactory, getEnvironment());
}
/**
* Build a {@link ClassPathBeanDefinitionScanner} for the given bean factory.
* <p>
* This should be pre-configured with the {@code Environment} (if desired) but not
* with a {@code BeanNameGenerator} or {@code ScopeMetadataResolver} yet.
* @param beanFactory the bean factory to load bean definitions into
* @return the class path bean definition scanner
* @see #getEnvironment()
* @see #getBeanNameGenerator()
* @see #getScopeMetadataResolver()
*/
protected ClassPathBeanDefinitionScanner getClassPathBeanDefinitionScanner(
DefaultListableBeanFactory beanFactory) {
return new ClassPathBeanDefinitionScanner(beanFactory, true, getEnvironment());
}
@Override
protected Resource getResourceByPath(String path) {
// We must be careful not to expose classpath resources

View File

@ -0,0 +1,221 @@
/*
* 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
*
* https://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.servlet.context;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Supplier;
import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigRegistry;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.AnnotationScopeMetadataResolver;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ScopeMetadataResolver;
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.ObjectUtils;
import org.springframework.web.context.support.GenericWebApplicationContext;
/**
* {@link GenericWebApplicationContext}that accepts annotated classes as input - in
* particular {@link Configuration @Configuration}-annotated classes, but also plain
* {@link Component @Component} classes and JSR-330 compliant classes using
* {@code javax.inject} annotations. Allows for registering classes one by one (specifying
* class names as config location) as well as for classpath scanning (specifying base
* packages as config location).
* <p>
* Note: In case of multiple {@code @Configuration} classes, later {@code @Bean}
* definitions will override ones defined in earlier loaded files. This can be leveraged
* to deliberately override certain bean definitions via an extra Configuration class.
*
* @author Stephane Nicoll
* @since 2.2.0
* @see #register(Class...)
* @see #scan(String...)
*/
public class AnnotationConfigServletWebApplicationContext
extends GenericWebApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();
private String[] basePackages;
/**
* Create a new {@link AnnotationConfigServletWebApplicationContext} that needs to be
* populated through {@link #register} calls and then manually {@linkplain #refresh
* refreshed}.
*/
public AnnotationConfigServletWebApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* Create a new {@link AnnotationConfigServletWebApplicationContext} with the given
* {@code DefaultListableBeanFactory}. The context needs to be populated through
* {@link #register} calls and then manually {@linkplain #refresh refreshed}.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
*/
public AnnotationConfigServletWebApplicationContext(
DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* Create a new {@link AnnotationConfigServletWebApplicationContext}, deriving bean
* definitions from the given annotated classes and automatically refreshing the
* context.
* @param annotatedClasses one or more annotated classes, e.g. {@code @Configuration}
* classes
*/
public AnnotationConfigServletWebApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
/**
* Create a new {@link AnnotationConfigServletWebApplicationContext}, scanning for
* bean definitions in the given packages and automatically refreshing the context.
* @param basePackages the packages to check for annotated classes
*/
public AnnotationConfigServletWebApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
/**
* {@inheritDoc}
* <p>
* Delegates given environment to underlying {@link AnnotatedBeanDefinitionReader} and
* {@link ClassPathBeanDefinitionScanner} members.
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
/**
* Provide a custom {@link BeanNameGenerator} for use with
* {@link AnnotatedBeanDefinitionReader} and/or
* {@link ClassPathBeanDefinitionScanner}, if any.
* <p>
* Default is
* {@link org.springframework.context.annotation.AnnotationBeanNameGenerator}.
* <p>
* Any call to this method must occur prior to calls to {@link #register(Class...)}
* and/or {@link #scan(String...)}.
* @param beanNameGenerator the bean name generator
* @see AnnotatedBeanDefinitionReader#setBeanNameGenerator
* @see ClassPathBeanDefinitionScanner#setBeanNameGenerator
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.reader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator);
this.getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
beanNameGenerator);
}
/**
* Set the {@link ScopeMetadataResolver} to use for detected bean classes.
* <p>
* The default is an {@link AnnotationScopeMetadataResolver}.
* <p>
* Any call to this method must occur prior to calls to {@link #register(Class...)}
* and/or {@link #scan(String...)}.
* @param scopeMetadataResolver the scope metadata resolver
*/
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
this.reader.setScopeMetadataResolver(scopeMetadataResolver);
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
/**
* Register one or more annotated classes to be processed. Note that
* {@link #refresh()} must be called in order for the context to fully process the new
* class.
* <p>
* Calls to {@code #register} are idempotent; adding the same annotated class more
* than once has no additional effect.
* @param annotatedClasses one or more annotated classes, e.g. {@code @Configuration}
* classes
* @see #scan(String...)
* @see #refresh()
*/
@Override
public final void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses,
"At least one annotated class must be specified");
this.annotatedClasses.addAll(Arrays.asList(annotatedClasses));
}
/**
* Perform a scan within the specified base packages. Note that {@link #refresh()}
* must be called in order for the context to fully process the new class.
* @param basePackages the packages to check for annotated classes
* @see #register(Class...)
* @see #refresh()
*/
@Override
public final void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.basePackages = basePackages;
}
@Override
protected void prepareRefresh() {
this.scanner.clearCache();
super.prepareRefresh();
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (!ObjectUtils.isEmpty(this.basePackages)) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
@Override
public <T> void registerBean(String beanName, Class<T> beanClass,
Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
this.reader.registerBean(beanClass, beanName, supplier, customizers);
}
}

View File

@ -33,7 +33,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
/**
* {@link ServletWebServerApplicationContext} that accepts annotated classes as input - in
@ -51,7 +50,7 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
* @see #register(Class...)
* @see #scan(String...)
* @see ServletWebServerApplicationContext
* @see AnnotationConfigWebApplicationContext
* @see AnnotationConfigServletWebApplicationContext
*/
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {

View File

@ -62,6 +62,7 @@ import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWeb
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
import org.springframework.boot.web.reactive.context.StandardReactiveWebEnvironment;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@ -97,7 +98,6 @@ import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ConfigurableWebEnvironment;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
@ -318,8 +318,8 @@ public class SpringApplicationTests {
@Test
public void specificWebApplicationContextClassDetectWebApplicationType() {
SpringApplication application = new SpringApplication(ExampleConfig.class);
application
.setApplicationContextClass(AnnotationConfigWebApplicationContext.class);
application.setApplicationContextClass(
AnnotationConfigServletWebApplicationContext.class);
assertThat(application.getWebApplicationType())
.isEqualTo(WebApplicationType.SERVLET);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 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,11 +22,11 @@ import com.samskivert.mustache.Mustache;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@ -44,7 +44,7 @@ public class MustacheViewTests {
private MockHttpServletResponse response = new MockHttpServletResponse();
private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
private AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
@Before
public void init() {