Commit 099e188f authored by Phillip Webb's avatar Phillip Webb

Unify WebServerFactoryCustomizers

Replace `ReactiveWebServerCustomizer` and `WebServerFactoryCustomizer`
with a unified `WebServerFactoryCustomizer`.

Fixes gh-8558
parent 13db69bf
...@@ -48,9 +48,8 @@ import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactor ...@@ -48,9 +48,8 @@ import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactor
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -171,8 +170,8 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -171,8 +170,8 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static class ServerFactoryCustomization static class ServerFactoryCustomization implements
implements ServletWebServerFactoryCustomizer, Ordered { WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
@Autowired @Autowired
private ListableBeanFactory beanFactory; private ListableBeanFactory beanFactory;
...@@ -215,7 +214,8 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -215,7 +214,8 @@ public class EndpointWebMvcChildContextConfiguration {
} }
webServerFactory.setServerHeader(this.server.getServerHeader()); webServerFactory.setServerHeader(this.server.getServerHeader());
webServerFactory.setAddress(this.managementServerProperties.getAddress()); webServerFactory.setAddress(this.managementServerProperties.getAddress());
webServerFactory.addErrorPages(new ErrorPage(this.server.getError().getPath())); webServerFactory
.addErrorPages(new ErrorPage(this.server.getError().getPath()));
} }
} }
...@@ -343,14 +343,7 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -343,14 +343,7 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static abstract class AccessLogCustomizer<T extends ServletWebServerFactory> static abstract class AccessLogCustomizer implements Ordered {
implements ServletWebServerFactoryCustomizer, Ordered {
private final Class<T> factoryClass;
AccessLogCustomizer(Class<T> factoryClass) {
this.factoryClass = factoryClass;
}
protected String customizePrefix(String prefix) { protected String customizePrefix(String prefix) {
return "management_" + prefix; return "management_" + prefix;
...@@ -361,23 +354,10 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -361,23 +354,10 @@ public class EndpointWebMvcChildContextConfiguration {
return 1; return 1;
} }
@Override
public void customize(ConfigurableServletWebServerFactory serverFactory) {
if (this.factoryClass.isInstance(serverFactory)) {
customize(this.factoryClass.cast(serverFactory));
}
}
abstract void customize(T webServerFactory);
} }
static class TomcatAccessLogCustomizer static class TomcatAccessLogCustomizer extends AccessLogCustomizer
extends AccessLogCustomizer<TomcatServletWebServerFactory> { implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
TomcatAccessLogCustomizer() {
super(TomcatServletWebServerFactory.class);
}
@Override @Override
public void customize(TomcatServletWebServerFactory serverFactory) { public void customize(TomcatServletWebServerFactory serverFactory) {
...@@ -400,16 +380,13 @@ public class EndpointWebMvcChildContextConfiguration { ...@@ -400,16 +380,13 @@ public class EndpointWebMvcChildContextConfiguration {
} }
static class UndertowAccessLogCustomizer static class UndertowAccessLogCustomizer extends AccessLogCustomizer
extends AccessLogCustomizer<UndertowServletWebServerFactory> { implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
UndertowAccessLogCustomizer() {
super(UndertowServletWebServerFactory.class);
}
@Override @Override
public void customize(UndertowServletWebServerFactory serverFactory) { public void customize(UndertowServletWebServerFactory serverFactory) {
serverFactory.setAccessLogPrefix(customizePrefix(serverFactory.getAccessLogPrefix())); serverFactory.setAccessLogPrefix(
customizePrefix(serverFactory.getAccessLogPrefix()));
} }
} }
......
...@@ -32,10 +32,10 @@ import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfi ...@@ -32,10 +32,10 @@ import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfi
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
...@@ -162,8 +162,8 @@ public class JolokiaAutoConfigurationTests { ...@@ -162,8 +162,8 @@ public class JolokiaAutoConfigurationTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
...@@ -50,12 +50,10 @@ import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; ...@@ -50,12 +50,10 @@ import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer; import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.InitParameterConfiguringServletContextInitializer; import org.springframework.boot.web.servlet.server.InitParameterConfiguringServletContextInitializer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.EnvironmentAware; import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
...@@ -63,15 +61,15 @@ import org.springframework.util.ObjectUtils; ...@@ -63,15 +61,15 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* Customizer used by an {@link ServletWebServerFactory} when an * Default {@link WebServerFactoryCustomizer} for {@link ServerProperties}.
* {@link ServletWebServerFactoryCustomizerBeanPostProcessor} is active.
* *
* @author Brian Clozel * @author Brian Clozel
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 2.0.0 * @since 2.0.0
*/ */
public class DefaultServletWebServerFactoryCustomizer public class DefaultServletWebServerFactoryCustomizer
implements ServletWebServerFactoryCustomizer, EnvironmentAware, Ordered { implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>,
EnvironmentAware, Ordered {
private final ServerProperties serverProperties; private final ServerProperties serverProperties;
......
...@@ -48,7 +48,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties ...@@ -48,7 +48,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.web.server.ErrorPage; import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar; import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry; import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.ConditionContext;
......
...@@ -23,9 +23,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; ...@@ -23,9 +23,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.HttpEncodingProperties.Type; import org.springframework.boot.autoconfigure.web.HttpEncodingProperties.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
...@@ -67,8 +67,8 @@ public class HttpEncodingAutoConfiguration { ...@@ -67,8 +67,8 @@ public class HttpEncodingAutoConfiguration {
return new LocaleCharsetMappingsCustomizer(this.properties); return new LocaleCharsetMappingsCustomizer(this.properties);
} }
private static class LocaleCharsetMappingsCustomizer private static class LocaleCharsetMappingsCustomizer implements
implements ServletWebServerFactoryCustomizer, Ordered { WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
private final HttpEncodingProperties properties; private final HttpEncodingProperties properties;
......
...@@ -44,8 +44,8 @@ import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; ...@@ -44,8 +44,8 @@ import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor; import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -124,8 +124,8 @@ public class ServletWebServerFactoryAutoConfiguration { ...@@ -124,8 +124,8 @@ public class ServletWebServerFactoryAutoConfiguration {
} }
/** /**
* Registers a {@link ServletWebServerFactoryCustomizerBeanPostProcessor}. Registered * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
* via {@link ImportBeanDefinitionRegistrar} for early registration. * {@link ImportBeanDefinitionRegistrar} for early registration.
*/ */
public static class BeanPostProcessorsRegistrar public static class BeanPostProcessorsRegistrar
implements ImportBeanDefinitionRegistrar, BeanFactoryAware { implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
...@@ -146,8 +146,8 @@ public class ServletWebServerFactoryAutoConfiguration { ...@@ -146,8 +146,8 @@ public class ServletWebServerFactoryAutoConfiguration {
return; return;
} }
registerSyntheticBeanIfMissing(registry, registerSyntheticBeanIfMissing(registry,
"ServletWebServerCustomizerBeanPostProcessor", "webServerFactoryCustomizerBeanPostProcessor",
ServletWebServerFactoryCustomizerBeanPostProcessor.class); WebServerFactoryCustomizerBeanPostProcessor.class);
registerSyntheticBeanIfMissing(registry, registerSyntheticBeanIfMissing(registry,
"errorPageRegistrarBeanPostProcessor", "errorPageRegistrarBeanPostProcessor",
ErrorPageRegistrarBeanPostProcessor.class); ErrorPageRegistrarBeanPostProcessor.class);
......
...@@ -18,20 +18,17 @@ package org.springframework.boot.autoconfigure.webflux; ...@@ -18,20 +18,17 @@ package org.springframework.boot.autoconfigure.webflux;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory; import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerCustomizer; import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
/** /**
* Customizer used by an {@link ReactiveWebServerFactory} when an * Default {@link WebServerFactoryCustomizer} for reactive servers.
* {@link ServletWebServerFactoryCustomizerBeanPostProcessor} is active.
* *
* @author Brian Clozel * @author Brian Clozel
* @since 2.0.0 * @since 2.0.0
*/ */
public class DefaultReactiveWebServerCustomizer public class DefaultReactiveWebServerCustomizer implements
implements ReactiveWebServerCustomizer, Ordered { WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory>, Ordered {
private final ServerProperties serverProperties; private final ServerProperties serverProperties;
......
...@@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean ...@@ -28,7 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.reactive.server.ReactiveWebServerCustomizerBeanPostProcessor; import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -62,7 +62,7 @@ public class ReactiveWebServerAutoConfiguration { ...@@ -62,7 +62,7 @@ public class ReactiveWebServerAutoConfiguration {
} }
/** /**
* Registers a {@link ReactiveWebServerCustomizerBeanPostProcessor}. Registered via * Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
* {@link ImportBeanDefinitionRegistrar} for early registration. * {@link ImportBeanDefinitionRegistrar} for early registration.
*/ */
public static class BeanPostProcessorsRegistrar public static class BeanPostProcessorsRegistrar
...@@ -84,12 +84,12 @@ public class ReactiveWebServerAutoConfiguration { ...@@ -84,12 +84,12 @@ public class ReactiveWebServerAutoConfiguration {
return; return;
} }
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType( if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(
ReactiveWebServerCustomizerBeanPostProcessor.class, true, false))) { WebServerFactoryCustomizerBeanPostProcessor.class, true, false))) {
RootBeanDefinition beanDefinition = new RootBeanDefinition( RootBeanDefinition beanDefinition = new RootBeanDefinition(
ReactiveWebServerCustomizerBeanPostProcessor.class); WebServerFactoryCustomizerBeanPostProcessor.class);
beanDefinition.setSynthetic(true); beanDefinition.setSynthetic(true);
registry.registerBeanDefinition( registry.registerBeanDefinition(
"reactiveWebServerCustomizerBeanPostProcessor", beanDefinition); "webServerFactoryCustomizerBeanPostProcessor", beanDefinition);
} }
} }
......
...@@ -23,9 +23,11 @@ import org.eclipse.jetty.websocket.jsr356.server.ServerContainer; ...@@ -23,9 +23,11 @@ import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;
/** /**
* {@link WebSocketContainerCustomizer} for {@link JettyServletWebServerFactory}. * WebSocket customizer for {@link JettyServletWebServerFactory}.
* *
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
...@@ -33,10 +35,10 @@ import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; ...@@ -33,10 +35,10 @@ import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
* @since 1.2.0 * @since 1.2.0
*/ */
public class JettyWebSocketContainerCustomizer public class JettyWebSocketContainerCustomizer
extends WebSocketContainerCustomizer<JettyServletWebServerFactory> { implements WebServerFactoryCustomizer<JettyServletWebServerFactory>, Ordered {
@Override @Override
protected void doCustomize(JettyServletWebServerFactory factory) { public void customize(JettyServletWebServerFactory factory) {
factory.addConfigurations(new AbstractConfiguration() { factory.addConfigurations(new AbstractConfiguration() {
@Override @Override
...@@ -49,4 +51,9 @@ public class JettyWebSocketContainerCustomizer ...@@ -49,4 +51,9 @@ public class JettyWebSocketContainerCustomizer
}); });
} }
@Override
public int getOrder() {
return 0;
}
} }
...@@ -23,11 +23,13 @@ import org.apache.catalina.Context; ...@@ -23,11 +23,13 @@ import org.apache.catalina.Context;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
* {@link WebSocketContainerCustomizer} for {@link TomcatServletWebServerFactory}. * WebSocket customizer for {@link TomcatServletWebServerFactory}.
* *
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
...@@ -35,7 +37,7 @@ import org.springframework.util.ReflectionUtils; ...@@ -35,7 +37,7 @@ import org.springframework.util.ReflectionUtils;
* @since 1.2.0 * @since 1.2.0
*/ */
public class TomcatWebSocketContainerCustomizer public class TomcatWebSocketContainerCustomizer
extends WebSocketContainerCustomizer<TomcatServletWebServerFactory> { implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
private static final String TOMCAT_7_LISTENER_TYPE = "org.apache.catalina.deploy.ApplicationListener"; private static final String TOMCAT_7_LISTENER_TYPE = "org.apache.catalina.deploy.ApplicationListener";
...@@ -44,7 +46,7 @@ public class TomcatWebSocketContainerCustomizer ...@@ -44,7 +46,7 @@ public class TomcatWebSocketContainerCustomizer
private static final String WS_LISTENER = "org.apache.tomcat.websocket.server.WsContextListener"; private static final String WS_LISTENER = "org.apache.tomcat.websocket.server.WsContextListener";
@Override @Override
public void doCustomize(TomcatServletWebServerFactory factory) { public void customize(TomcatServletWebServerFactory factory) {
factory.addContextCustomizers(new TomcatContextCustomizer() { factory.addContextCustomizers(new TomcatContextCustomizer() {
@Override @Override
...@@ -89,4 +91,9 @@ public class TomcatWebSocketContainerCustomizer ...@@ -89,4 +91,9 @@ public class TomcatWebSocketContainerCustomizer
} }
} }
@Override
public int getOrder() {
return 0;
}
} }
...@@ -21,22 +21,29 @@ import io.undertow.websockets.jsr.WebSocketDeploymentInfo; ...@@ -21,22 +21,29 @@ import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer; import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.Ordered;
/** /**
* {@link WebSocketContainerCustomizer} for {@link UndertowServletWebServerFactory}. * WebSocket customizer for {@link UndertowServletWebServerFactory}.
* *
* @author Phillip Webb * @author Phillip Webb
* @since 1.2.0 * @since 1.2.0
*/ */
public class UndertowWebSocketContainerCustomizer public class UndertowWebSocketContainerCustomizer
extends WebSocketContainerCustomizer<UndertowServletWebServerFactory> { implements WebServerFactoryCustomizer<UndertowServletWebServerFactory>, Ordered {
@Override @Override
protected void doCustomize(UndertowServletWebServerFactory factory) { public void customize(UndertowServletWebServerFactory factory) {
WebsocketDeploymentInfoCustomizer customizer = new WebsocketDeploymentInfoCustomizer(); WebsocketDeploymentInfoCustomizer customizer = new WebsocketDeploymentInfoCustomizer();
factory.addDeploymentInfoCustomizers(customizer); factory.addDeploymentInfoCustomizers(customizer);
} }
@Override
public int getOrder() {
return 0;
}
private static class WebsocketDeploymentInfoCustomizer private static class WebsocketDeploymentInfoCustomizer
implements UndertowDeploymentInfoCustomizer { implements UndertowDeploymentInfoCustomizer {
......
/*
* Copyright 2012-2017 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.autoconfigure.websocket;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
/**
* {@link ServletWebServerFactoryCustomizer} to configure websockets for a given
* {@link ServletWebServerFactory}.
*
* @param <T> the {@link ServletWebServerFactory}
* @author Dave Syer
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.2.0
*/
public abstract class WebSocketContainerCustomizer<T extends ServletWebServerFactory>
implements ServletWebServerFactoryCustomizer, Ordered {
@Override
public int getOrder() {
return 0;
}
@SuppressWarnings("unchecked")
@Override
public void customize(ConfigurableServletWebServerFactory factory) {
if (getWebServerFactoryType().isAssignableFrom(factory.getClass())) {
doCustomize((T) factory);
}
}
protected Class<?> getWebServerFactoryType() {
return ResolvableType.forClass(WebSocketContainerCustomizer.class, getClass())
.resolveGeneric();
}
protected abstract void doCustomize(T factory);
}
...@@ -34,12 +34,12 @@ import org.springframework.boot.test.util.EnvironmentTestUtils; ...@@ -34,12 +34,12 @@ import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory; import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
...@@ -165,8 +165,8 @@ public class DefaultServletWebServerFactoryCustomizerTests { ...@@ -165,8 +165,8 @@ public class DefaultServletWebServerFactoryCustomizerTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
...@@ -183,8 +183,8 @@ public class DefaultServletWebServerFactoryCustomizerTests { ...@@ -183,8 +183,8 @@ public class DefaultServletWebServerFactoryCustomizerTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
...@@ -201,8 +201,8 @@ public class DefaultServletWebServerFactoryCustomizerTests { ...@@ -201,8 +201,8 @@ public class DefaultServletWebServerFactoryCustomizerTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
...@@ -211,15 +211,8 @@ public class DefaultServletWebServerFactoryCustomizerTests { ...@@ -211,15 +211,8 @@ public class DefaultServletWebServerFactoryCustomizerTests {
protected static class CustomizeConfig { protected static class CustomizeConfig {
@Bean @Bean
public ServletWebServerFactoryCustomizer webServerFactoryCustomizer() { public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer() {
return new ServletWebServerFactoryCustomizer() { return (serverFactory) -> serverFactory.setPort(3000);
@Override
public void customize(ConfigurableServletWebServerFactory serverFactory) {
serverFactory.setPort(3000);
}
};
} }
} }
......
...@@ -29,12 +29,12 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon ...@@ -29,12 +29,12 @@ import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoCon
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration; import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter; import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory.RegisteredFilter; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory.RegisteredFilter;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnection;
...@@ -104,8 +104,8 @@ public class FilterOrderingIntegrationTests { ...@@ -104,8 +104,8 @@ public class FilterOrderingIntegrationTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
...@@ -31,11 +31,11 @@ import org.junit.rules.ExpectedException; ...@@ -31,11 +31,11 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter; import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter; import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.annotation.AnnotationAwareOrderComparator;
...@@ -145,8 +145,7 @@ public class HttpEncodingAutoConfigurationTests { ...@@ -145,8 +145,7 @@ public class HttpEncodingAutoConfigurationTests {
@Test @Test
public void noLocaleCharsetMapping() { public void noLocaleCharsetMapping() {
load(EmptyConfiguration.class); load(EmptyConfiguration.class);
Map<String, ServletWebServerFactoryCustomizer> beans = this.context Map<String, WebServerFactoryCustomizer<?>> beans = getWebServerFactoryCustomizerBeans();
.getBeansOfType(ServletWebServerFactoryCustomizer.class);
assertThat(beans.size()).isEqualTo(1); assertThat(beans.size()).isEqualTo(1);
assertThat(this.context.getBean(MockServletWebServerFactory.class) assertThat(this.context.getBean(MockServletWebServerFactory.class)
.getLocaleCharsetMappings().size()).isEqualTo(0); .getLocaleCharsetMappings().size()).isEqualTo(0);
...@@ -156,8 +155,7 @@ public class HttpEncodingAutoConfigurationTests { ...@@ -156,8 +155,7 @@ public class HttpEncodingAutoConfigurationTests {
public void customLocaleCharsetMappings() { public void customLocaleCharsetMappings() {
load(EmptyConfiguration.class, "spring.http.encoding.mapping.en:UTF-8", load(EmptyConfiguration.class, "spring.http.encoding.mapping.en:UTF-8",
"spring.http.encoding.mapping.fr_FR:UTF-8"); "spring.http.encoding.mapping.fr_FR:UTF-8");
Map<String, ServletWebServerFactoryCustomizer> beans = this.context Map<String, WebServerFactoryCustomizer<?>> beans = getWebServerFactoryCustomizerBeans();
.getBeansOfType(ServletWebServerFactoryCustomizer.class);
assertThat(beans.size()).isEqualTo(1); assertThat(beans.size()).isEqualTo(1);
assertThat(this.context.getBean(MockServletWebServerFactory.class) assertThat(this.context.getBean(MockServletWebServerFactory.class)
.getLocaleCharsetMappings().size()).isEqualTo(2); .getLocaleCharsetMappings().size()).isEqualTo(2);
...@@ -169,6 +167,11 @@ public class HttpEncodingAutoConfigurationTests { ...@@ -169,6 +167,11 @@ public class HttpEncodingAutoConfigurationTests {
.isEqualTo(Charset.forName("UTF-8")); .isEqualTo(Charset.forName("UTF-8"));
} }
@SuppressWarnings({ "unchecked", "rawtypes" })
private Map<String, WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() {
return (Map) this.context.getBeansOfType(WebServerFactoryCustomizer.class);
}
private void assertCharacterEncodingFilter(CharacterEncodingFilter actual, private void assertCharacterEncodingFilter(CharacterEncodingFilter actual,
String encoding, boolean forceRequestEncoding, String encoding, boolean forceRequestEncoding,
boolean forceResponseEncoding) { boolean forceResponseEncoding) {
...@@ -235,8 +238,8 @@ public class HttpEncodingAutoConfigurationTests { ...@@ -235,8 +238,8 @@ public class HttpEncodingAutoConfigurationTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
...@@ -44,9 +44,9 @@ import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; ...@@ -44,9 +44,9 @@ import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -59,7 +59,7 @@ import static org.mockito.Mockito.spy; ...@@ -59,7 +59,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
/** /**
* Tests for {@link ServerProperties} {@link ServletWebServerFactoryCustomizer}. * Tests for {@link ServerProperties} {@link WebServerFactoryCustomizer}.
* *
* @author Brian Clozel * @author Brian Clozel
*/ */
......
...@@ -27,12 +27,12 @@ import org.springframework.beans.BeansException; ...@@ -27,12 +27,12 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -246,7 +246,7 @@ public class ServletWebServerFactoryAutoConfigurationTests { ...@@ -246,7 +246,7 @@ public class ServletWebServerFactoryAutoConfigurationTests {
@Component @Component
public static class CallbackEmbeddedServerFactoryCustomizer public static class CallbackEmbeddedServerFactoryCustomizer
implements ServletWebServerFactoryCustomizer { implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override @Override
public void customize(ConfigurableServletWebServerFactory serverFactory) { public void customize(ConfigurableServletWebServerFactory serverFactory) {
......
...@@ -43,11 +43,11 @@ import org.springframework.boot.autoconfigure.validation.SpringValidator; ...@@ -43,11 +43,11 @@ import org.springframework.boot.autoconfigure.validation.SpringValidator;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WelcomePageHandlerMapping; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.WelcomePageHandlerMapping;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter; import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter;
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory; import org.springframework.boot.web.servlet.server.MockServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
...@@ -773,8 +773,8 @@ public class WebMvcAutoConfigurationTests { ...@@ -773,8 +773,8 @@ public class WebMvcAutoConfigurationTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
...@@ -23,8 +23,9 @@ import org.junit.rules.ExpectedException; ...@@ -23,8 +23,9 @@ import org.junit.rules.ExpectedException;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.boot.web.reactive.server.ReactiveWebServerCustomizer; import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationContextException;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -50,7 +51,7 @@ public class ReactiveWebServerAutoConfigurationTests { ...@@ -50,7 +51,7 @@ public class ReactiveWebServerAutoConfigurationTests {
this.context = new ReactiveWebServerApplicationContext(BaseConfiguration.class); this.context = new ReactiveWebServerApplicationContext(BaseConfiguration.class);
assertThat(this.context.getBeansOfType(ReactiveWebServerFactory.class)) assertThat(this.context.getBeansOfType(ReactiveWebServerFactory.class))
.hasSize(1); .hasSize(1);
assertThat(this.context.getBeansOfType(ReactiveWebServerCustomizer.class)) assertThat(this.context.getBeansOfType(WebServerFactoryCustomizer.class))
.hasSize(1); .hasSize(1);
assertThat(this.context.getBeansOfType(DefaultReactiveWebServerCustomizer.class)) assertThat(this.context.getBeansOfType(DefaultReactiveWebServerCustomizer.class))
.hasSize(1); .hasSize(1);
...@@ -115,7 +116,7 @@ public class ReactiveWebServerAutoConfigurationTests { ...@@ -115,7 +116,7 @@ public class ReactiveWebServerAutoConfigurationTests {
protected static class ReactiveWebServerCustomization { protected static class ReactiveWebServerCustomization {
@Bean @Bean
public ReactiveWebServerCustomizer reactiveWebServerCustomizer() { public WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> reactiveWebServerCustomizer() {
return (server) -> server.setPort(9000); return (server) -> server.setPort(9000);
} }
......
...@@ -29,9 +29,9 @@ import org.junit.Test; ...@@ -29,9 +29,9 @@ import org.junit.Test;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
...@@ -92,8 +92,8 @@ public class WebSocketAutoConfigurationTests { ...@@ -92,8 +92,8 @@ public class WebSocketAutoConfigurationTests {
static class CommonConfiguration { static class CommonConfiguration {
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() { public WebServerFactoryCustomizerBeanPostProcessor ServletWebServerCustomizerBeanPostProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
...@@ -16,13 +16,10 @@ ...@@ -16,13 +16,10 @@
package org.springframework.boot.context.embedded; package org.springframework.boot.context.embedded;
import org.apache.catalina.Context;
import org.apache.tomcat.util.http.LegacyCookieProcessor; import org.apache.tomcat.util.http.LegacyCookieProcessor;
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -34,33 +31,16 @@ import org.springframework.context.annotation.Configuration; ...@@ -34,33 +31,16 @@ import org.springframework.context.annotation.Configuration;
public class TomcatLegacyCookieProcessorExample { public class TomcatLegacyCookieProcessorExample {
/** /**
* Configuration class that declares the required * Configuration class that declares the required {@link WebServerFactoryCustomizer}.
* {@link ServletWebServerFactoryCustomizer}.
*/ */
@Configuration @Configuration
static class LegacyCookieProcessorConfiguration { static class LegacyCookieProcessorConfiguration {
// tag::customizer[] // tag::customizer[]
@Bean @Bean
public ServletWebServerFactoryCustomizer cookieProcessorCustomizer() { public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return new ServletWebServerFactoryCustomizer() { return (serverFactory) -> serverFactory.addContextCustomizers(
(context) -> context.setCookieProcessor(new LegacyCookieProcessor()));
@Override
public void customize(ConfigurableServletWebServerFactory serverFactory) {
if (serverFactory instanceof TomcatServletWebServerFactory) {
((TomcatServletWebServerFactory) serverFactory)
.addContextCustomizers(new TomcatContextCustomizer() {
@Override
public void customize(Context context) {
context.setCookieProcessor(new LegacyCookieProcessor());
}
});
}
}
};
} }
// end::customizer[] // end::customizer[]
......
...@@ -24,8 +24,8 @@ import org.springframework.boot.SpringApplication; ...@@ -24,8 +24,8 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.TomcatLegacyCookieProcessorExample.LegacyCookieProcessorConfiguration; import org.springframework.boot.context.embedded.TomcatLegacyCookieProcessorExample.LegacyCookieProcessorConfiguration;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer; import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactoryCustomizerBeanPostProcessor;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -42,8 +42,8 @@ public class TomcatLegacyCookieProcessorExampleTests { ...@@ -42,8 +42,8 @@ public class TomcatLegacyCookieProcessorExampleTests {
public void cookieProcessorIsCustomized() { public void cookieProcessorIsCustomized() {
ServletWebServerApplicationContext applicationContext = (ServletWebServerApplicationContext) new SpringApplication( ServletWebServerApplicationContext applicationContext = (ServletWebServerApplicationContext) new SpringApplication(
TestConfiguration.class, LegacyCookieProcessorConfiguration.class).run(); TestConfiguration.class, LegacyCookieProcessorConfiguration.class).run();
Context context = (Context) ((TomcatWebServer) applicationContext Context context = (Context) ((TomcatWebServer) applicationContext.getWebServer())
.getWebServer()).getTomcat().getHost().findChildren()[0]; .getTomcat().getHost().findChildren()[0];
assertThat(context.getCookieProcessor()) assertThat(context.getCookieProcessor())
.isInstanceOf(LegacyCookieProcessor.class); .isInstanceOf(LegacyCookieProcessor.class);
} }
...@@ -57,8 +57,8 @@ public class TomcatLegacyCookieProcessorExampleTests { ...@@ -57,8 +57,8 @@ public class TomcatLegacyCookieProcessorExampleTests {
} }
@Bean @Bean
public ServletWebServerFactoryCustomizerBeanPostProcessor postProcessor() { public WebServerFactoryCustomizerBeanPostProcessor postProcessor() {
return new ServletWebServerFactoryCustomizerBeanPostProcessor(); return new WebServerFactoryCustomizerBeanPostProcessor();
} }
} }
......
/*
* Copyright 2012-2017 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.server;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
/**
* {@link BeanPostProcessor} that applies all {@link ReactiveWebServerCustomizer}s from
* the bean factory to {@link ConfigurableReactiveWebServerFactory} beans.
*
* @author Brian Clozel
* @author Stephane Nicoll
* @since 2.0.0
*/
public class ReactiveWebServerCustomizerBeanPostProcessor
implements BeanPostProcessor, BeanFactoryAware {
private ListableBeanFactory beanFactory;
private List<ReactiveWebServerCustomizer> customizers;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ListableBeanFactory) beanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof ConfigurableReactiveWebServerFactory) {
postProcessBeforeInitialization((ConfigurableReactiveWebServerFactory) bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
private void postProcessBeforeInitialization(ConfigurableReactiveWebServerFactory bean) {
for (ReactiveWebServerCustomizer customizer : getCustomizers()) {
customizer.customize(bean);
}
}
private Collection<ReactiveWebServerCustomizer> getCustomizers() {
if (this.customizers == null) {
// Look up does not include the parent context
this.customizers = new ArrayList<>(this.beanFactory
.getBeansOfType(ReactiveWebServerCustomizer.class, false, false)
.values());
Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
this.customizers = Collections.unmodifiableList(this.customizers);
}
return this.customizers;
}
}
...@@ -20,12 +20,14 @@ import java.net.InetAddress; ...@@ -20,12 +20,14 @@ import java.net.InetAddress;
import java.util.Set; import java.util.Set;
/** /**
* Simple interface that represents customizations to an web server factory. * Simple interface that represents customizations to a {@link WebServerFactory}.
* *
* @author Phillip Webb
* @author Brian Clozel * @author Brian Clozel
* @since 2.0.0 * @since 2.0.0
*/ */
public interface ConfigurableWebServerFactory extends ErrorPageRegistry { public interface ConfigurableWebServerFactory
extends WebServerFactory, ErrorPageRegistry {
/** /**
* Sets the port that the web server should listen on. If not specified port '8080' * Sets the port that the web server should listen on. If not specified port '8080'
......
...@@ -14,21 +14,17 @@ ...@@ -14,21 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.web.reactive.server; package org.springframework.boot.web.server;
/** /**
* Strategy interface for customizing auto-configured reactive web servers. Any beans of * Tagging interface for factories that create a {@link WebServer}.
* this type will get a callback with the server factory before the server itself is *
* started, so you can set the port, address, error pages etc. * @author Phillip Webb
* @author Brian Clozel
* @since 2.0.0 * @since 2.0.0
* @see WebServer
* @see org.springframework.boot.web.servlet.server.ServletWebServerFactory
* @see org.springframework.boot.web.reactive.server.ReactiveWebServerFactory
*/ */
@FunctionalInterface public interface WebServerFactory {
public interface ReactiveWebServerCustomizer {
/**
* Customize the specified {@link ConfigurableReactiveWebServerFactory}.
* @param server the server to customize
*/
void customize(ConfigurableReactiveWebServerFactory server);
} }
...@@ -14,32 +14,34 @@ ...@@ -14,32 +14,34 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.web.servlet.server; package org.springframework.boot.web.server;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
/** /**
* Strategy interface for customizing auto-configured web server factory. Any beans of * Strategy interface for customizing {@link WebServerFactory web server factories}. Any
* this type will get a callback with the server factory before the server itself is * beans of this type will get a callback with the server factory before the server itself
* started, so you can set the port, address, error pages etc. * is started, so you can set the port, address, error pages etc.
* <p> * <p>
* Beware: calls to this interface are usually made from a * Beware: calls to this interface are usually made from a
* {@link ServletWebServerFactoryCustomizerBeanPostProcessor} which is a * {@link WebServerFactoryCustomizerBeanPostProcessor} which is a
* {@link BeanPostProcessor} (so called very early in the ApplicationContext lifecycle). * {@link BeanPostProcessor} (so called very early in the ApplicationContext lifecycle).
* It might be safer to lookup dependencies lazily in the enclosing BeanFactory rather * It might be safer to lookup dependencies lazily in the enclosing BeanFactory rather
* than injecting them with {@code @Autowired}. * than injecting them with {@code @Autowired}.
* *
* @param <T> The configurable web server factory
* @author Phillip Webb
* @author Dave Syer * @author Dave Syer
* @author Brian Clozel
* @since 2.0.0 * @since 2.0.0
* @see ServletWebServerFactoryCustomizerBeanPostProcessor * @see WebServerFactoryCustomizerBeanPostProcessor
*/ */
@FunctionalInterface public interface WebServerFactoryCustomizer<T extends WebServerFactory> {
public interface ServletWebServerFactoryCustomizer {
/** /**
* Customize the specified {@link ConfigurableServletWebServerFactory}. * Customize the specified {@link WebServerFactory}.
* @param serverFactory the server factory to customize * @param server the server to customize
*/ */
void customize(ConfigurableServletWebServerFactory serverFactory); void customize(T server);
} }
...@@ -14,41 +14,45 @@ ...@@ -14,41 +14,45 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.web.servlet.server; package org.springframework.boot.web.server;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* {@link BeanPostProcessor} that applies all {@link ServletWebServerFactoryCustomizer}s * {@link BeanPostProcessor} that applies all {@link WebServerFactoryCustomizer} beans
* from the bean factory to {@link ConfigurableServletWebServerFactory} beans. * from the bean factory to {@link WebServerFactory} beans.
* *
* @author Dave Syer * @author Dave Syer
* @author Phillip Webb * @author Phillip Webb
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 2.0.0 * @since 2.0.0
*/ */
public class ServletWebServerFactoryCustomizerBeanPostProcessor public class WebServerFactoryCustomizerBeanPostProcessor
implements BeanPostProcessor, BeanFactoryAware { implements BeanPostProcessor, BeanFactoryAware {
private ListableBeanFactory beanFactory; private ListableBeanFactory beanFactory;
private List<ServletWebServerFactoryCustomizer> customizers; private List<WebServerFactoryCustomizer<?>> customizers;
@Override @Override
public void setBeanFactory(BeanFactory beanFactory) { public void setBeanFactory(BeanFactory beanFactory) {
Assert.isInstanceOf(ListableBeanFactory.class, beanFactory, Assert.isInstanceOf(ListableBeanFactory.class, beanFactory,
"ServletWebServerFactoryCustomizerBeanPostProcessor can only be used " "WebServerCustomizerBeanPostProcessor can only be used "
+ "with a ListableBeanFactory"); + "with a ListableBeanFactory");
this.beanFactory = (ListableBeanFactory) beanFactory; this.beanFactory = (ListableBeanFactory) beanFactory;
} }
...@@ -56,8 +60,8 @@ public class ServletWebServerFactoryCustomizerBeanPostProcessor ...@@ -56,8 +60,8 @@ public class ServletWebServerFactoryCustomizerBeanPostProcessor
@Override @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException { throws BeansException {
if (bean instanceof ConfigurableServletWebServerFactory) { if (bean instanceof WebServerFactory) {
postProcessBeforeInitialization((ConfigurableServletWebServerFactory) bean); postProcessBeforeInitialization((WebServerFactory) bean);
} }
return bean; return bean;
} }
...@@ -68,23 +72,58 @@ public class ServletWebServerFactoryCustomizerBeanPostProcessor ...@@ -68,23 +72,58 @@ public class ServletWebServerFactoryCustomizerBeanPostProcessor
return bean; return bean;
} }
private void postProcessBeforeInitialization( private void postProcessBeforeInitialization(WebServerFactory bean) {
ConfigurableServletWebServerFactory bean) { for (WebServerFactoryCustomizer<?> customizer : getCustomizers()) {
for (ServletWebServerFactoryCustomizer customizer : getCustomizers()) { Class<?> type = ResolvableType
customizer.customize(bean); .forClass(WebServerFactoryCustomizer.class, customizer.getClass())
.getGeneric().resolve(WebServerFactory.class);
if (type.isInstance(bean)) {
invokeCustomizer(customizer, bean);
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void invokeCustomizer(WebServerFactoryCustomizer customizer,
WebServerFactory webServerFactory) {
try {
customizer.customize(webServerFactory);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || msg.startsWith(webServerFactory.getClass().getName())) {
// Possibly a lambda-defined listener which we could not resolve the
// generic event type for
logLambdaDebug(customizer, ex);
}
else {
throw ex;
}
}
}
private void logLambdaDebug(WebServerFactoryCustomizer<?> customizer,
ClassCastException ex) {
Log logger = LogFactory.getLog(getClass());
if (logger.isDebugEnabled()) {
logger.debug("Non-matching factory type for customizer: " + customizer, ex);
} }
} }
private Collection<ServletWebServerFactoryCustomizer> getCustomizers() { private Collection<WebServerFactoryCustomizer<?>> getCustomizers() {
if (this.customizers == null) { if (this.customizers == null) {
// Look up does not include the parent context // Look up does not include the parent context
this.customizers = new ArrayList<>(this.beanFactory this.customizers = new ArrayList<>(getWebServerFactoryCustomizerBeans());
.getBeansOfType(ServletWebServerFactoryCustomizer.class, false, false)
.values());
Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE); Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
this.customizers = Collections.unmodifiableList(this.customizers); this.customizers = Collections.unmodifiableList(this.customizers);
} }
return this.customizers; return this.customizers;
} }
@SuppressWarnings({ "unchecked", "rawtypes" })
private Collection<WebServerFactoryCustomizer<?>> getWebServerFactoryCustomizerBeans() {
return (Collection) this.beanFactory
.getBeansOfType(WebServerFactoryCustomizer.class, false, false).values();
}
} }
...@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; ...@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.MimeMappings; import org.springframework.boot.web.server.MimeMappings;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletContextInitializer;
/** /**
...@@ -37,7 +38,7 @@ import org.springframework.boot.web.servlet.ServletContextInitializer; ...@@ -37,7 +38,7 @@ import org.springframework.boot.web.servlet.ServletContextInitializer;
* @author Brian Clozel * @author Brian Clozel
* @since 2.0.0 * @since 2.0.0
* @see ServletWebServerFactory * @see ServletWebServerFactory
* @see ServletWebServerFactoryCustomizer * @see WebServerFactoryCustomizer
*/ */
public interface ConfigurableServletWebServerFactory public interface ConfigurableServletWebServerFactory
extends ConfigurableWebServerFactory { extends ConfigurableWebServerFactory {
......
/*
* Copyright 2012-2017 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.server;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link WebServerFactoryCustomizerBeanPostProcessor}.
*
* @author Phillip Webb
*/
public class WebServerFactoryCustomizerBeanPostProcessorTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private WebServerFactoryCustomizerBeanPostProcessor processor = new WebServerFactoryCustomizerBeanPostProcessor();
@Mock
private ListableBeanFactory beanFactory;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.processor.setBeanFactory(this.beanFactory);
}
@Test
public void setBeanFactoryWhenNotListableShouldThrowException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("WebServerCustomizerBeanPostProcessor can only "
+ "be used with a ListableBeanFactory");
this.processor.setBeanFactory(mock(BeanFactory.class));
}
@Test
public void postProcessBeforeShouldReturnBean() throws Exception {
addMockBeans(Collections.emptyMap());
Object bean = new Object();
Object result = this.processor.postProcessBeforeInitialization(bean, "foo");
assertThat(result).isSameAs(bean);
}
@Test
public void postProcessAfterShouldReturnBean() throws Exception {
addMockBeans(Collections.emptyMap());
Object bean = new Object();
Object result = this.processor.postProcessAfterInitialization(bean, "foo");
assertThat(result).isSameAs(bean);
}
@Test
public void postProcessAfterShouldCallInterfaceCustomizers() throws Exception {
Map<String, Object> beans = addInterfaceBeans();
addMockBeans(beans);
postProcessBeforeInitialization(WebServerFactory.class);
assertThat(wasCalled(beans, "one")).isFalse();
assertThat(wasCalled(beans, "two")).isFalse();
assertThat(wasCalled(beans, "all")).isTrue();
}
@Test
public void postProcessAfterWhenWebServerFactoryOneShouldCallInterfaceCustomizers()
throws Exception {
Map<String, Object> beans = addInterfaceBeans();
addMockBeans(beans);
postProcessBeforeInitialization(WebServerFactoryOne.class);
assertThat(wasCalled(beans, "one")).isTrue();
assertThat(wasCalled(beans, "two")).isFalse();
assertThat(wasCalled(beans, "all")).isTrue();
}
@Test
public void postProcessAfterWhenWebServerFactoryTwoShouldCallInterfaceCustomizers()
throws Exception {
Map<String, Object> beans = addInterfaceBeans();
addMockBeans(beans);
postProcessBeforeInitialization(WebServerFactoryTwo.class);
assertThat(wasCalled(beans, "one")).isFalse();
assertThat(wasCalled(beans, "two")).isTrue();
assertThat(wasCalled(beans, "all")).isTrue();
}
private Map<String, Object> addInterfaceBeans() {
WebServerFactoryOneCustomizer oneCustomizer = new WebServerFactoryOneCustomizer();
WebServerFactoryTwoCustomizer twoCustomizer = new WebServerFactoryTwoCustomizer();
WebServerFactoryAllCustomizer allCustomizer = new WebServerFactoryAllCustomizer();
Map<String, Object> beans = new LinkedHashMap<>();
beans.put("one", oneCustomizer);
beans.put("two", twoCustomizer);
beans.put("all", allCustomizer);
return beans;
}
@Test
public void postProcessAfterShouldCallLambdaCustomizers() throws Exception {
List<String> called = new ArrayList<>();
addLambdaBeans(called);
postProcessBeforeInitialization(WebServerFactory.class);
assertThat(called).containsExactly("all");
}
@Test
public void postProcessAfterWhenWebServerFactoryOneShouldCallLambdaCustomizers()
throws Exception {
List<String> called = new ArrayList<>();
addLambdaBeans(called);
postProcessBeforeInitialization(WebServerFactoryOne.class);
assertThat(called).containsExactly("one", "all");
}
@Test
public void postProcessAfterWhenWebServerFactoryTwoShouldCallLambdaCustomizers()
throws Exception {
List<String> called = new ArrayList<>();
addLambdaBeans(called);
postProcessBeforeInitialization(WebServerFactoryTwo.class);
assertThat(called).containsExactly("two", "all");
}
private void addLambdaBeans(List<String> called) {
WebServerFactoryCustomizer<WebServerFactoryOne> one = (f) -> called.add("one");
WebServerFactoryCustomizer<WebServerFactoryTwo> two = (f) -> called.add("two");
WebServerFactoryCustomizer<WebServerFactory> all = (f) -> called.add("all");
Map<String, Object> beans = new LinkedHashMap<String, Object>();
beans.put("one", one);
beans.put("two", two);
beans.put("all", all);
addMockBeans(beans);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private void addMockBeans(Map<String, ?> beans) {
given(this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false,
false)).willReturn((Map<String, WebServerFactoryCustomizer>) beans);
}
private void postProcessBeforeInitialization(Class<?> type) {
this.processor.postProcessBeforeInitialization(mock(type), "foo");
}
private boolean wasCalled(Map<String, ?> beans, String name) {
return ((MockWebServerFactoryCustomizer<?>) beans.get(name)).wasCalled();
}
private interface WebServerFactoryOne extends WebServerFactory {
}
private interface WebServerFactoryTwo extends WebServerFactory {
}
private static class MockWebServerFactoryCustomizer<T extends WebServerFactory>
implements WebServerFactoryCustomizer<T> {
private boolean called;
@Override
public void customize(T server) {
this.called = true;
}
public boolean wasCalled() {
return this.called;
}
}
private static class WebServerFactoryOneCustomizer
extends MockWebServerFactoryCustomizer<WebServerFactoryOne> {
}
private static class WebServerFactoryTwoCustomizer
extends MockWebServerFactoryCustomizer<WebServerFactoryTwo> {
}
private static class WebServerFactoryAllCustomizer
extends MockWebServerFactoryCustomizer<WebServerFactory> {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment