Spring中的BeanPostProcessor
一、何谓BeanProcessor
BeanPostProcessor是SpringFramework里非常重要的核心接口之一,我先贴出一段源代码:
- /*
- * Copyright 2002-2015 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.beans.factory.config;
- import org.springframework.beans.BeansException;
- /**
- * Factory hook that allows for custom modification of new bean instances,
- * e.g. checking for marker interfaces or wrapping them with proxies.
- *
- * <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
- * bean definitions and apply them to any beans subsequently created.
- * Plain bean factories allow for programmatic registration of post-processors,
- * applying to all beans created through this factory.
- *
- * <p>Typically, post-processors that populate beans via marker interfaces
- * or the like will implement {@link #postProcessBeforeInitialization},
- * while post-processors that wrap beans with proxies will normally
- * implement {@link #postProcessAfterInitialization}.
- *
- * @author Juergen Hoeller
- * @since 10.10.2003
- * @see InstantiationAwareBeanPostProcessor
- * @see DestructionAwareBeanPostProcessor
- * @see ConfigurableBeanFactory#addBeanPostProcessor
- * @see BeanFactoryPostProcessor
- */
- public interface BeanPostProcessor {
- /**
- * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
- * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
- * or a custom init-method). The bean will already be populated with property values.
- * The returned bean instance may be a wrapper around the original.
- * @param bean the new bean instance
- * @param beanName the name of the bean
- * @return the bean instance to use, either the original or a wrapped one;
- * if {@code null}, no subsequent BeanPostProcessors will be invoked
- * @throws org.springframework.beans.BeansException in case of errors
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
- */
- Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
- /**
- * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
- * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
- * or a custom init-method). The bean will already be populated with property values.
- * The returned bean instance may be a wrapper around the original.
- * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
- * instance and the objects created by the FactoryBean (as of Spring 2.0). The
- * post-processor can decide whether to apply to either the FactoryBean or created
- * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
- * <p>This callback will also be invoked after a short-circuiting triggered by a
- * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
- * in contrast to all other BeanPostProcessor callbacks.
- * @param bean the new bean instance
- * @param beanName the name of the bean
- * @return the bean instance to use, either the original or a wrapped one;
- * if {@code null}, no subsequent BeanPostProcessors will be invoked
- * @throws org.springframework.beans.BeansException in case of errors
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
- * @see org.springframework.beans.factory.FactoryBean
- */
- Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
- }
在这里我先简单解释一下其注释的含义:
这个接口允许我们自定义修改新bean的一个实例,比如说:检查它们的接口或者将他们包装成代理对象等,ApplicationContexts能自动察觉到我们在BeanProcessor里对对象作出的改变,并在后来创建该对象时应用其对应的改变。
这两个方法分别对应IOC容器对对象初始化前的操作和对象初始化后的操作
下面我们来演示一个例子:
StudentEntity:
- package org.hzgj.spring.study.entity;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class StudentEntity {
- private Integer id;
- private String name;
- private Map<String,String> memerories= new HashMap<>();
- public Map<String, String> getMemerories() {
- return memerories;
- }
- public void setMemerories(Map<String, String> memerories) {
- this.memerories = memerories;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public StudentEntity() {
- // System.out.println("studentEntity initializer....");
- }
- @Override
- public String toString() {
- return "StudentEntity{" +
- "id=" + id +
- ", name='" + name + '\'' +
- '}';
- }
- private List<String> hobbies=new ArrayList<>();
- public List<String> getHobbies() {
- return hobbies;
- }
- public void setHobbies(List<String> hobbies) {
- this.hobbies = hobbies;
- }
- }
TestBeanPostProcessor:
- package org.hzgj.spring.study.context;
- import org.hzgj.spring.study.entity.StudentEntity;
- import org.springframework.beans.BeansException;
- import org.springframework.beans.factory.config.BeanPostProcessor;
- public class TestBeanPostProcessor implements BeanPostProcessor {
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof StudentEntity) {
- StudentEntity studentEntity = new StudentEntity();
- studentEntity.setName(beanName);
- return studentEntity;
- }
- return bean;
- }
- @Override
- public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- if (bean instanceof StudentEntity)
- System.out.println(bean);
- return bean;
- }
- }
Main方法:
- package org.hzgj.spring.study;
- import org.hzgj.spring.study.entity.StudentEntity;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class Main {
- public static void main(String[] args) {
- ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
- StudentEntity studentEntity = applicationContext.getBean(StudentEntity.class);
- System.out.println(studentEntity.getName());
- }
- }
spring-config.xml关键代码:
- <bean id="studentEntity" class="org.hzgj.spring.study.entity.StudentEntity" depends-on="studentServiceWithFactory">
- <property name="hobbies" ref="hobbies">
- </property>
- <property name="memerories">
- <map>
- <entry key="glad" value="play"/>
- <entry key="cry" value="cry"/>
- </map>
- </property>
- <property name="name" value="admin"/>
- </bean>
- <bean id="beanPostProcessor" class="org.hzgj.spring.study.context.TestBeanPostProcessor" />
运行得到如下结果:
我们可以看到在配置文件里定义的bean属性已经发生改变
二、SpringFramework中BeanPostProcessor经典应用场景
1.初始化BeanPostProcessor的源码
根据 ClassPathXmlApplicationContext的构造方法,我们可以看到该类初始化的时候会调用refresh():
- /**
- * Create a new ClassPathXmlApplicationContext with the given parent,
- * loading the definitions from the given XML files.
- * @param configLocations array of resource locations
- * @param refresh whether to automatically refresh the context,
- * loading all bean definitions and creating all singletons.
- * Alternatively, call refresh manually after further configuring the context.
- * @param parent the parent context
- * @throws BeansException if context creation failed
- * @see #refresh()
- */
- public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
- throws BeansException {
- super(parent);
- setConfigLocations(configLocations);
- if (refresh) {
- refresh();
- }
- }
那么紧接着在AbstractApplicationContext中找到refresh()方法:
- @Override
- public void refresh() throws BeansException, IllegalStateException {
- synchronized (this.startupShutdownMonitor) {
- // Prepare this context for refreshing.
- prepareRefresh();
- // Tell the subclass to refresh the internal bean factory.
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- // Prepare the bean factory for use in this context.
- prepareBeanFactory(beanFactory);
- try {
- // Allows post-processing of the bean factory in context subclasses.
- postProcessBeanFactory(beanFactory);
- // Invoke factory processors registered as beans in the context.
- invokeBeanFactoryPostProcessors(beanFactory);
- // Register bean processors that intercept bean creation.
- registerBeanPostProcessors(beanFactory);
- // Initialize message source for this context.
- initMessageSource();
- // Initialize event multicaster for this context.
- initApplicationEventMulticaster();
- // Initialize other special beans in specific context subclasses.
- onRefresh();
- // Check for listener beans and register them.
- registerListeners();
- // Instantiate all remaining (non-lazy-init) singletons.
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- finishRefresh();
- }
- catch (BeansException ex) {
- if (logger.isWarnEnabled()) {
- logger.warn("Exception encountered during context initialization - " +
- "cancelling refresh attempt: " + ex);
- }
- // Destroy already created singletons to avoid dangling resources.
- destroyBeans();
- // Reset 'active' flag.
- cancelRefresh(ex);
- // Propagate exception to caller.
- throw ex;
- }
- finally {
- // Reset common introspection caches in Spring's core, since we
- // might not ever need metadata for singleton beans anymore...
- resetCommonCaches();
- }
- }
- }
那么在这里Spring会进行一系列的初始化操作,我们请留意registerBeanPostProcessors(beanFactory);这句代码,追踪一下我们可以看到在该方法里注册Processor:
- public static void registerBeanPostProcessors(
- ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
- String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
- // Register BeanPostProcessorChecker that logs an info message when
- // a bean is created during BeanPostProcessor instantiation, i.e. when
- // a bean is not eligible for getting processed by all BeanPostProcessors.
- int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
- beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
- // Separate between BeanPostProcessors that implement PriorityOrdered,
- // Ordered, and the rest.
- List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
- List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
- List<String> orderedPostProcessorNames = new ArrayList<String>();
- List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
- for (String ppName : postProcessorNames) {
- if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- priorityOrderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
- orderedPostProcessorNames.add(ppName);
- }
- else {
- nonOrderedPostProcessorNames.add(ppName);
- }
- }
- // First, register the BeanPostProcessors that implement PriorityOrdered.
- sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
- // Next, register the BeanPostProcessors that implement Ordered.
- List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
- for (String ppName : orderedPostProcessorNames) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- orderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- sortPostProcessors(orderedPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, orderedPostProcessors);
- // Now, register all regular BeanPostProcessors.
- List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
- for (String ppName : nonOrderedPostProcessorNames) {
- BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
- nonOrderedPostProcessors.add(pp);
- if (pp instanceof MergedBeanDefinitionPostProcessor) {
- internalPostProcessors.add(pp);
- }
- }
- registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
- // Finally, re-register all internal BeanPostProcessors.
- sortPostProcessors(internalPostProcessors, beanFactory);
- registerBeanPostProcessors(beanFactory, internalPostProcessors);
- // Re-register post-processor for detecting inner beans as ApplicationListeners,
- // moving it to the end of the processor chain (for picking up proxies etc).
- beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
- }
2.@Autowired实现的代码跟踪
注意AutowiredAnnotationBeanPostProcessor最终也是BeanPostProcessor的实现类,具体类的描述我就不再这里阐述了,大家可自行查看源码
3、SpringBoot中的定制化内嵌web容器
这个EmbeddedServletContainerCustomizerBeanPostProcessor直接实现的就是BeanPostProcessor,该类下请关注如下方法:
- @Override
- public Object postProcessBeforeInitialization(Object bean, String beanName)
- throws BeansException {
- if (bean instanceof ConfigurableEmbeddedServletContainer) {
- postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);
- }
- return bean;
- }
- private void postProcessBeforeInitialization(
- ConfigurableEmbeddedServletContainer bean) {
- for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {
- customizer.customize(bean);
- }
- }
- private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
- if (this.customizers == null) {
- // Look up does not include the parent context
- this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(
- this.beanFactory
- .getBeansOfType(EmbeddedServletContainerCustomizer.class,
- false, false)
- .values());
- Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
- this.customizers = Collections.unmodifiableList(this.customizers);
- }
- return this.customizers;
- }
这里面有一个接口:EmbeddedServletContainerCustomizer 该接口有个实现类 ServerProperties 熟悉springboot外部化配置原理的同胞们其实一看便知
- /*
- * Copyright 2012-2018 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.web;
- import java.io.File;
- import java.net.InetAddress;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import javax.servlet.SessionCookieConfig;
- import javax.servlet.SessionTrackingMode;
- import io.undertow.Undertow.Builder;
- import io.undertow.UndertowOptions;
- import org.apache.catalina.Context;
- import org.apache.catalina.connector.Connector;
- import org.apache.catalina.valves.AccessLogValve;
- import org.apache.catalina.valves.ErrorReportValve;
- import org.apache.catalina.valves.RemoteIpValve;
- import org.apache.coyote.AbstractProtocol;
- import org.apache.coyote.ProtocolHandler;
- import org.apache.coyote.http11.AbstractHttp11Protocol;
- import org.eclipse.jetty.server.AbstractConnector;
- import org.eclipse.jetty.server.ConnectionFactory;
- import org.eclipse.jetty.server.Handler;
- import org.eclipse.jetty.server.HttpConfiguration;
- import org.eclipse.jetty.server.Server;
- import org.eclipse.jetty.server.handler.ContextHandler;
- import org.eclipse.jetty.server.handler.HandlerCollection;
- import org.eclipse.jetty.server.handler.HandlerWrapper;
- import org.springframework.boot.autoconfigure.web.ServerProperties.Session.Cookie;
- import org.springframework.boot.cloud.CloudPlatform;
- import org.springframework.boot.context.embedded.Compression;
- import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
- import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
- import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
- import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
- import org.springframework.boot.context.embedded.InitParameterConfiguringServletContextInitializer;
- import org.springframework.boot.context.embedded.JspServlet;
- import org.springframework.boot.context.embedded.Ssl;
- import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
- import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
- import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
- import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
- import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
- import org.springframework.boot.context.embedded.undertow.UndertowBuilderCustomizer;
- import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
- import org.springframework.boot.context.properties.NestedConfigurationProperty;
- import org.springframework.boot.web.servlet.ServletContextInitializer;
- import org.springframework.context.EnvironmentAware;
- import org.springframework.core.Ordered;
- import org.springframework.core.env.Environment;
- import org.springframework.util.Assert;
- import org.springframework.util.ObjectUtils;
- import org.springframework.util.StringUtils;
- /**
- * {@link ConfigurationProperties} for a web server (e.g. port and path settings). Will be
- * used to customize an {@link EmbeddedServletContainerFactory} when an
- * {@link EmbeddedServletContainerCustomizerBeanPostProcessor} is active.
- *
- * @author Dave Syer
- * @author Stephane Nicoll
- * @author Andy Wilkinson
- * @author Ivan Sopov
- * @author Marcos Barbero
- * @author Eddú Meléndez
- * @author Quinten De Swaef
- * @author Venil Noronha
- * @author Aurélien Leboulanger
- */
- @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
- public class ServerProperties
- implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
- /**
- * Server HTTP port.
- */
- private Integer port;
- /**
- * Network address to which the server should bind to.
- */
- private InetAddress address;
- /**
- * Context path of the application.
- */
- private String contextPath;
- /**
- * Display name of the application.
- */
- private String displayName = "application";
- @NestedConfigurationProperty
- private ErrorProperties error = new ErrorProperties();
- /**
- * Path of the main dispatcher servlet.
- */
- private String servletPath = "/";
- /**
- * ServletContext parameters.
- */
- private final Map<String, String> contextParameters = new HashMap<String, String>();
- /**
- * If X-Forwarded-* headers should be applied to the HttpRequest.
- */
- private Boolean useForwardHeaders;
- /**
- * Value to use for the Server response header (no header is sent if empty).
- */
- private String serverHeader;
- /**
- * Maximum size in bytes of the HTTP message header.
- */
- private int maxHttpHeaderSize = 0; // bytes
- /**
- * Maximum size in bytes of the HTTP post content.
- */
- private int maxHttpPostSize = 0; // bytes
- /**
- * Time in milliseconds that connectors will wait for another HTTP request before
- * closing the connection. When not set, the connector's container-specific default
- * will be used. Use a value of -1 to indicate no (i.e. infinite) timeout.
- */
- private Integer connectionTimeout;
- private Session session = new Session();
- @NestedConfigurationProperty
- private Ssl ssl;
- @NestedConfigurationProperty
- private Compression compression = new Compression();
- @NestedConfigurationProperty
- private JspServlet jspServlet;
- private final Tomcat tomcat = new Tomcat();
- private final Jetty jetty = new Jetty();
- private final Undertow undertow = new Undertow();
- private Environment environment;
- @Override
- public int getOrder() {
- return 0;
- }
- @Override
- public void setEnvironment(Environment environment) {
- this.environment = environment;
- }
- @Override
- public void customize(ConfigurableEmbeddedServletContainer container) {
- if (getPort() != null) {
- container.setPort(getPort());
- }
- if (getAddress() != null) {
- container.setAddress(getAddress());
- }
- if (getContextPath() != null) {
- container.setContextPath(getContextPath());
- }
- if (getDisplayName() != null) {
- container.setDisplayName(getDisplayName());
- }
- if (getSession().getTimeout() != null) {
- container.setSessionTimeout(getSession().getTimeout());
- }
- container.setPersistSession(getSession().isPersistent());
- container.setSessionStoreDir(getSession().getStoreDir());
- if (getSsl() != null) {
- container.setSsl(getSsl());
- }
- if (getJspServlet() != null) {
- container.setJspServlet(getJspServlet());
- }
- if (getCompression() != null) {
- container.setCompression(getCompression());
- }
- container.setServerHeader(getServerHeader());
- if (container instanceof TomcatEmbeddedServletContainerFactory) {
- getTomcat().customizeTomcat(this,
- (TomcatEmbeddedServletContainerFactory) container);
- }
- if (container instanceof JettyEmbeddedServletContainerFactory) {
- getJetty().customizeJetty(this,
- (JettyEmbeddedServletContainerFactory) container);
- }
- if (container instanceof UndertowEmbeddedServletContainerFactory) {
- getUndertow().customizeUndertow(this,
- (UndertowEmbeddedServletContainerFactory) container);
- }
- container.addInitializers(new SessionConfiguringInitializer(this.session));
- container.addInitializers(new InitParameterConfiguringServletContextInitializer(
- getContextParameters()));
- }
- public String getServletMapping() {
- if (this.servletPath.equals("") || this.servletPath.equals("/")) {
- return "/";
- }
- if (this.servletPath.contains("*")) {
- return this.servletPath;
- }
- if (this.servletPath.endsWith("/")) {
- return this.servletPath + "*";
- }
- return this.servletPath + "/*";
- }
- public String getPath(String path) {
- String prefix = getServletPrefix();
- if (!path.startsWith("/")) {
- path = "/" + path;
- }
- return prefix + path;
- }
- public String getServletPrefix() {
- String result = this.servletPath;
- if (result.contains("*")) {
- result = result.substring(0, result.indexOf("*"));
- }
- if (result.endsWith("/")) {
- result = result.substring(0, result.length() - 1);
- }
- return result;
- }
- public String[] getPathsArray(Collection<String> paths) {
- String[] result = new String[paths.size()];
- int i = 0;
- for (String path : paths) {
- result[i++] = getPath(path);
- }
- return result;
- }
- public String[] getPathsArray(String[] paths) {
- String[] result = new String[paths.length];
- int i = 0;
- for (String path : paths) {
- result[i++] = getPath(path);
- }
- return result;
- }
- public void setLoader(String value) {
- // no op to support Tomcat running as a traditional container (not embedded)
- }
- public Integer getPort() {
- return this.port;
- }
- public void setPort(Integer port) {
- this.port = port;
- }
- public InetAddress getAddress() {
- return this.address;
- }
- public void setAddress(InetAddress address) {
- this.address = address;
- }
- public String getContextPath() {
- return this.contextPath;
- }
- public void setContextPath(String contextPath) {
- this.contextPath = cleanContextPath(contextPath);
- }
- private String cleanContextPath(String contextPath) {
- if (StringUtils.hasText(contextPath) && contextPath.endsWith("/")) {
- return contextPath.substring(0, contextPath.length() - 1);
- }
- return contextPath;
- }
- public String getDisplayName() {
- return this.displayName;
- }
- public void setDisplayName(String displayName) {
- this.displayName = displayName;
- }
- public String getServletPath() {
- return this.servletPath;
- }
- public void setServletPath(String servletPath) {
- Assert.notNull(servletPath, "ServletPath must not be null");
- this.servletPath = servletPath;
- }
- public Map<String, String> getContextParameters() {
- return this.contextParameters;
- }
- public Boolean isUseForwardHeaders() {
- return this.useForwardHeaders;
- }
- public void setUseForwardHeaders(Boolean useForwardHeaders) {
- this.useForwardHeaders = useForwardHeaders;
- }
- public String getServerHeader() {
- return this.serverHeader;
- }
- public void setServerHeader(String serverHeader) {
- this.serverHeader = serverHeader;
- }
- public int getMaxHttpHeaderSize() {
- return this.maxHttpHeaderSize;
- }
- public void setMaxHttpHeaderSize(int maxHttpHeaderSize) {
- this.maxHttpHeaderSize = maxHttpHeaderSize;
- }
- @Deprecated
- @DeprecatedConfigurationProperty(reason = "Use dedicated property for each container.")
- public int getMaxHttpPostSize() {
- return this.maxHttpPostSize;
- }
- @Deprecated
- public void setMaxHttpPostSize(int maxHttpPostSize) {
- this.maxHttpPostSize = maxHttpPostSize;
- this.jetty.setMaxHttpPostSize(maxHttpPostSize);
- this.tomcat.setMaxHttpPostSize(maxHttpPostSize);
- this.undertow.setMaxHttpPostSize(maxHttpPostSize);
- }
- protected final boolean getOrDeduceUseForwardHeaders() {
- if (this.useForwardHeaders != null) {
- return this.useForwardHeaders;
- }
- CloudPlatform platform = CloudPlatform.getActive(this.environment);
- return (platform == null ? false : platform.isUsingForwardHeaders());
- }
- public Integer getConnectionTimeout() {
- return this.connectionTimeout;
- }
- public void setConnectionTimeout(Integer connectionTimeout) {
- this.connectionTimeout = connectionTimeout;
- }
- public ErrorProperties getError() {
- return this.error;
- }
- public Session getSession() {
- return this.session;
- }
- public void setSession(Session session) {
- this.session = session;
- }
- public Ssl getSsl() {
- return this.ssl;
- }
- public void setSsl(Ssl ssl) {
- this.ssl = ssl;
- }
- public Compression getCompression() {
- return this.compression;
- }
- public JspServlet getJspServlet() {
- return this.jspServlet;
- }
- public void setJspServlet(JspServlet jspServlet) {
- this.jspServlet = jspServlet;
- }
- public Tomcat getTomcat() {
- return this.tomcat;
- }
- public Jetty getJetty() {
- return this.jetty;
- }
- public Undertow getUndertow() {
- return this.undertow;
- }
- public static class Session {
- /**
- * Session timeout in seconds.
- */
- private Integer timeout;
- /**
- * Session tracking modes (one or more of the following: "cookie", "url", "ssl").
- */
- private Set<SessionTrackingMode> trackingModes;
- /**
- * Persist session data between restarts.
- */
- private boolean persistent;
- /**
- * Directory used to store session data.
- */
- private File storeDir;
- private Cookie cookie = new Cookie();
- public Cookie getCookie() {
- return this.cookie;
- }
- public Integer getTimeout() {
- return this.timeout;
- }
- public void setTimeout(Integer sessionTimeout) {
- this.timeout = sessionTimeout;
- }
- public Set<SessionTrackingMode> getTrackingModes() {
- return this.trackingModes;
- }
- public void setTrackingModes(Set<SessionTrackingMode> trackingModes) {
- this.trackingModes = trackingModes;
- }
- public boolean isPersistent() {
- return this.persistent;
- }
- public void setPersistent(boolean persistent) {
- this.persistent = persistent;
- }
- public File getStoreDir() {
- return this.storeDir;
- }
- public void setStoreDir(File storeDir) {
- this.storeDir = storeDir;
- }
- public static class Cookie {
- /**
- * Session cookie name.
- */
- private String name;
- /**
- * Domain for the session cookie.
- */
- private String domain;
- /**
- * Path of the session cookie.
- */
- private String path;
- /**
- * Comment for the session cookie.
- */
- private String comment;
- /**
- * "HttpOnly" flag for the session cookie.
- */
- private Boolean httpOnly;
- /**
- * "Secure" flag for the session cookie.
- */
- private Boolean secure;
- /**
- * Maximum age of the session cookie in seconds.
- */
- private Integer maxAge;
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDomain() {
- return this.domain;
- }
- public void setDomain(String domain) {
- this.domain = domain;
- }
- public String getPath() {
- return this.path;
- }
- public void setPath(String path) {
- this.path = path;
- }
- public String getComment() {
- return this.comment;
- }
- public void setComment(String comment) {
- this.comment = comment;
- }
- public Boolean getHttpOnly() {
- return this.httpOnly;
- }
- public void setHttpOnly(Boolean httpOnly) {
- this.httpOnly = httpOnly;
- }
- public Boolean getSecure() {
- return this.secure;
- }
- public void setSecure(Boolean secure) {
- this.secure = secure;
- }
- public Integer getMaxAge() {
- return this.maxAge;
- }
- public void setMaxAge(Integer maxAge) {
- this.maxAge = maxAge;
- }
- }
- }
- public static class Tomcat {
- /**
- * Access log configuration.
- */
- private final Accesslog accesslog = new Accesslog();
- /**
- * Regular expression that matches proxies that are to be trusted.
- */
- private String internalProxies = "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 10/8
- + "192\\.168\\.\\d{1,3}\\.\\d{1,3}|" // 192.168/16
- + "169\\.254\\.\\d{1,3}\\.\\d{1,3}|" // 169.254/16
- + "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" // 127/8
- + "172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" // 172.16/12
- + "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|"
- + "172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}";
- /**
- * Header that holds the incoming protocol, usually named "X-Forwarded-Proto".
- */
- private String protocolHeader;
- /**
- * Value of the protocol header that indicates that the incoming request uses SSL.
- */
- private String protocolHeaderHttpsValue = "https";
- /**
- * Name of the HTTP header used to override the original port value.
- */
- private String portHeader = "X-Forwarded-Port";
- /**
- * Name of the http header from which the remote ip is extracted..
- */
- private String remoteIpHeader;
- /**
- * Tomcat base directory. If not specified a temporary directory will be used.
- */
- private File basedir;
- /**
- * Delay in seconds between the invocation of backgroundProcess methods.
- */
- private int backgroundProcessorDelay = 30; // seconds
- /**
- * Maximum amount of worker threads.
- */
- private int maxThreads = 0; // Number of threads in protocol handler
- /**
- * Minimum amount of worker threads.
- */
- private int minSpareThreads = 0; // Minimum spare threads in protocol handler
- /**
- * Maximum size in bytes of the HTTP post content.
- */
- private int maxHttpPostSize = 0; // bytes
- /**
- * Maximum size in bytes of the HTTP message header.
- */
- private int maxHttpHeaderSize = 0; // bytes
- /**
- * Whether requests to the context root should be redirected by appending a / to
- * the path.
- */
- private Boolean redirectContextRoot;
- /**
- * Character encoding to use to decode the URI.
- */
- private Charset uriEncoding;
- /**
- * Maximum number of connections that the server will accept and process at any
- * given time. Once the limit has been reached, the operating system may still
- * accept connections based on the "acceptCount" property.
- */
- private int maxConnections = 0;
- /**
- * Maximum queue length for incoming connection requests when all possible request
- * processing threads are in use.
- */
- private int acceptCount = 0;
- /**
- * Comma-separated list of additional patterns that match jars to ignore for TLD
- * scanning. The special '?' and '*' characters can be used in the pattern to
- * match one and only one character and zero or more characters respectively.
- */
- private List<String> additionalTldSkipPatterns = new ArrayList<String>();
- public int getMaxThreads() {
- return this.maxThreads;
- }
- public void setMaxThreads(int maxThreads) {
- this.maxThreads = maxThreads;
- }
- public int getMinSpareThreads() {
- return this.minSpareThreads;
- }
- public void setMinSpareThreads(int minSpareThreads) {
- this.minSpareThreads = minSpareThreads;
- }
- public int getMaxHttpPostSize() {
- return this.maxHttpPostSize;
- }
- public void setMaxHttpPostSize(int maxHttpPostSize) {
- this.maxHttpPostSize = maxHttpPostSize;
- }
- public Accesslog getAccesslog() {
- return this.accesslog;
- }
- public int getBackgroundProcessorDelay() {
- return this.backgroundProcessorDelay;
- }
- public void setBackgroundProcessorDelay(int backgroundProcessorDelay) {
- this.backgroundProcessorDelay = backgroundProcessorDelay;
- }
- public File getBasedir() {
- return this.basedir;
- }
- public void setBasedir(File basedir) {
- this.basedir = basedir;
- }
- public String getInternalProxies() {
- return this.internalProxies;
- }
- public void setInternalProxies(String internalProxies) {
- this.internalProxies = internalProxies;
- }
- public String getProtocolHeader() {
- return this.protocolHeader;
- }
- public void setProtocolHeader(String protocolHeader) {
- this.protocolHeader = protocolHeader;
- }
- public String getProtocolHeaderHttpsValue() {
- return this.protocolHeaderHttpsValue;
- }
- public void setProtocolHeaderHttpsValue(String protocolHeaderHttpsValue) {
- this.protocolHeaderHttpsValue = protocolHeaderHttpsValue;
- }
- public String getPortHeader() {
- return this.portHeader;
- }
- public void setPortHeader(String portHeader) {
- this.portHeader = portHeader;
- }
- public Boolean getRedirectContextRoot() {
- return this.redirectContextRoot;
- }
- public void setRedirectContextRoot(Boolean redirectContextRoot) {
- this.redirectContextRoot = redirectContextRoot;
- }
- public String getRemoteIpHeader() {
- return this.remoteIpHeader;
- }
- public void setRemoteIpHeader(String remoteIpHeader) {
- this.remoteIpHeader = remoteIpHeader;
- }
- public Charset getUriEncoding() {
- return this.uriEncoding;
- }
- public void setUriEncoding(Charset uriEncoding) {
- this.uriEncoding = uriEncoding;
- }
- public int getMaxConnections() {
- return this.maxConnections;
- }
- public void setMaxConnections(int maxConnections) {
- this.maxConnections = maxConnections;
- }
- public int getAcceptCount() {
- return this.acceptCount;
- }
- public void setAcceptCount(int acceptCount) {
- this.acceptCount = acceptCount;
- }
- public List<String> getAdditionalTldSkipPatterns() {
- return this.additionalTldSkipPatterns;
- }
- public void setAdditionalTldSkipPatterns(List<String> additionalTldSkipPatterns) {
- this.additionalTldSkipPatterns = additionalTldSkipPatterns;
- }
- void customizeTomcat(ServerProperties serverProperties,
- TomcatEmbeddedServletContainerFactory factory) {
- if (getBasedir() != null) {
- factory.setBaseDirectory(getBasedir());
- }
- factory.setBackgroundProcessorDelay(Tomcat.this.backgroundProcessorDelay);
- customizeRemoteIpValve(serverProperties, factory);
- if (this.maxThreads > 0) {
- customizeMaxThreads(factory);
- }
- if (this.minSpareThreads > 0) {
- customizeMinThreads(factory);
- }
- int maxHttpHeaderSize = (serverProperties.getMaxHttpHeaderSize() > 0
- ? serverProperties.getMaxHttpHeaderSize() : this.maxHttpHeaderSize);
- if (maxHttpHeaderSize > 0) {
- customizeMaxHttpHeaderSize(factory, maxHttpHeaderSize);
- }
- if (this.maxHttpPostSize != 0) {
- customizeMaxHttpPostSize(factory, this.maxHttpPostSize);
- }
- if (this.accesslog.enabled) {
- customizeAccessLog(factory);
- }
- if (getUriEncoding() != null) {
- factory.setUriEncoding(getUriEncoding());
- }
- if (serverProperties.getConnectionTimeout() != null) {
- customizeConnectionTimeout(factory,
- serverProperties.getConnectionTimeout());
- }
- if (this.redirectContextRoot != null) {
- customizeRedirectContextRoot(factory, this.redirectContextRoot);
- }
- if (this.maxConnections > 0) {
- customizeMaxConnections(factory);
- }
- if (this.acceptCount > 0) {
- customizeAcceptCount(factory);
- }
- if (!ObjectUtils.isEmpty(this.additionalTldSkipPatterns)) {
- factory.getTldSkipPatterns().addAll(this.additionalTldSkipPatterns);
- }
- if (serverProperties.getError()
- .getIncludeStacktrace() == ErrorProperties.IncludeStacktrace.NEVER) {
- customizeErrorReportValve(factory);
- }
- }
- private void customizeErrorReportValve(
- TomcatEmbeddedServletContainerFactory factory) {
- factory.addContextCustomizers(new TomcatContextCustomizer() {
- @Override
- public void customize(Context context) {
- ErrorReportValve valve = new ErrorReportValve();
- valve.setShowServerInfo(false);
- valve.setShowReport(false);
- context.getParent().getPipeline().addValve(valve);
- }
- });
- }
- private void customizeAcceptCount(TomcatEmbeddedServletContainerFactory factory) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- @SuppressWarnings("deprecation")
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractProtocol) {
- AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
- protocol.setBacklog(Tomcat.this.acceptCount);
- }
- }
- });
- }
- private void customizeMaxConnections(
- TomcatEmbeddedServletContainerFactory factory) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractProtocol) {
- AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
- protocol.setMaxConnections(Tomcat.this.maxConnections);
- }
- }
- });
- }
- private void customizeConnectionTimeout(
- TomcatEmbeddedServletContainerFactory factory,
- final int connectionTimeout) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractProtocol) {
- AbstractProtocol<?> protocol = (AbstractProtocol<?>) handler;
- protocol.setConnectionTimeout(connectionTimeout);
- }
- }
- });
- }
- private void customizeRemoteIpValve(ServerProperties properties,
- TomcatEmbeddedServletContainerFactory factory) {
- String protocolHeader = getProtocolHeader();
- String remoteIpHeader = getRemoteIpHeader();
- // For back compatibility the valve is also enabled if protocol-header is set
- if (StringUtils.hasText(protocolHeader) || StringUtils.hasText(remoteIpHeader)
- || properties.getOrDeduceUseForwardHeaders()) {
- RemoteIpValve valve = new RemoteIpValve();
- valve.setProtocolHeader(StringUtils.hasLength(protocolHeader)
- ? protocolHeader : "X-Forwarded-Proto");
- if (StringUtils.hasLength(remoteIpHeader)) {
- valve.setRemoteIpHeader(remoteIpHeader);
- }
- // The internal proxies default to a white list of "safe" internal IP
- // addresses
- valve.setInternalProxies(getInternalProxies());
- valve.setPortHeader(getPortHeader());
- valve.setProtocolHeaderHttpsValue(getProtocolHeaderHttpsValue());
- // ... so it's safe to add this valve by default.
- factory.addEngineValves(valve);
- }
- }
- @SuppressWarnings("rawtypes")
- private void customizeMaxThreads(TomcatEmbeddedServletContainerFactory factory) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractProtocol) {
- AbstractProtocol protocol = (AbstractProtocol) handler;
- protocol.setMaxThreads(Tomcat.this.maxThreads);
- }
- }
- });
- }
- @SuppressWarnings("rawtypes")
- private void customizeMinThreads(TomcatEmbeddedServletContainerFactory factory) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractProtocol) {
- AbstractProtocol protocol = (AbstractProtocol) handler;
- protocol.setMinSpareThreads(Tomcat.this.minSpareThreads);
- }
- }
- });
- }
- @SuppressWarnings("rawtypes")
- private void customizeMaxHttpHeaderSize(
- TomcatEmbeddedServletContainerFactory factory,
- final int maxHttpHeaderSize) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- ProtocolHandler handler = connector.getProtocolHandler();
- if (handler instanceof AbstractHttp11Protocol) {
- AbstractHttp11Protocol protocol = (AbstractHttp11Protocol) handler;
- protocol.setMaxHttpHeaderSize(maxHttpHeaderSize);
- }
- }
- });
- }
- private void customizeMaxHttpPostSize(
- TomcatEmbeddedServletContainerFactory factory,
- final int maxHttpPostSize) {
- factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
- @Override
- public void customize(Connector connector) {
- connector.setMaxPostSize(maxHttpPostSize);
- }
- });
- }
- private void customizeAccessLog(TomcatEmbeddedServletContainerFactory factory) {
- AccessLogValve valve = new AccessLogValve();
- valve.setPattern(this.accesslog.getPattern());
- valve.setDirectory(this.accesslog.getDirectory());
- valve.setPrefix(this.accesslog.getPrefix());
- valve.setSuffix(this.accesslog.getSuffix());
- valve.setRenameOnRotate(this.accesslog.isRenameOnRotate());
- valve.setRequestAttributesEnabled(
- this.accesslog.isRequestAttributesEnabled());
- valve.setRotatable(this.accesslog.isRotate());
- valve.setBuffered(this.accesslog.isBuffered());
- valve.setFileDateFormat(this.accesslog.getFileDateFormat());
- factory.addEngineValves(valve);
- }
- private void customizeRedirectContextRoot(
- TomcatEmbeddedServletContainerFactory factory,
- final boolean redirectContextRoot) {
- factory.addContextCustomizers(new TomcatContextCustomizer() {
- @Override
- public void customize(Context context) {
- context.setMapperContextRootRedirectEnabled(redirectContextRoot);
- }
- });
- }
- public static class Accesslog {
- /**
- * Enable access log.
- */
- private boolean enabled = false;
- /**
- * Format pattern for access logs.
- */
- private String pattern = "common";
- /**
- * Directory in which log files are created. Can be relative to the tomcat
- * base dir or absolute.
- */
- private String directory = "logs";
- /**
- * Log file name prefix.
- */
- protected String prefix = "access_log";
- /**
- * Log file name suffix.
- */
- private String suffix = ".log";
- /**
- * Enable access log rotation.
- */
- private boolean rotate = true;
- /**
- * Defer inclusion of the date stamp in the file name until rotate time.
- */
- private boolean renameOnRotate;
- /**
- * Date format to place in log file name.
- */
- private String fileDateFormat = ".yyyy-MM-dd";
- /**
- * Set request attributes for IP address, Hostname, protocol and port used for
- * the request.
- */
- private boolean requestAttributesEnabled;
- /**
- * Buffer output such that it is only flushed periodically.
- */
- private boolean buffered = true;
- public boolean isEnabled() {
- return this.enabled;
- }
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
- public String getPattern() {
- return this.pattern;
- }
- public void setPattern(String pattern) {
- this.pattern = pattern;
- }
- public String getDirectory() {
- return this.directory;
- }
- public void setDirectory(String directory) {
- this.directory = directory;
- }
- public String getPrefix() {
- return this.prefix;
- }
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
- public String getSuffix() {
- return this.suffix;
- }
- public void setSuffix(String suffix) {
- this.suffix = suffix;
- }
- public boolean isRotate() {
- return this.rotate;
- }
- public void setRotate(boolean rotate) {
- this.rotate = rotate;
- }
- public boolean isRenameOnRotate() {
- return this.renameOnRotate;
- }
- public void setRenameOnRotate(boolean renameOnRotate) {
- this.renameOnRotate = renameOnRotate;
- }
- public String getFileDateFormat() {
- return this.fileDateFormat;
- }
- public void setFileDateFormat(String fileDateFormat) {
- this.fileDateFormat = fileDateFormat;
- }
- public boolean isRequestAttributesEnabled() {
- return this.requestAttributesEnabled;
- }
- public void setRequestAttributesEnabled(boolean requestAttributesEnabled) {
- this.requestAttributesEnabled = requestAttributesEnabled;
- }
- public boolean isBuffered() {
- return this.buffered;
- }
- public void setBuffered(boolean buffered) {
- this.buffered = buffered;
- }
- }
- }
- public static class Jetty {
- /**
- * Maximum size in bytes of the HTTP post or put content.
- */
- private int maxHttpPostSize = 0; // bytes
- /**
- * Number of acceptor threads to use.
- */
- private Integer acceptors;
- /**
- * Number of selector threads to use.
- */
- private Integer selectors;
- public int getMaxHttpPostSize() {
- return this.maxHttpPostSize;
- }
- public void setMaxHttpPostSize(int maxHttpPostSize) {
- this.maxHttpPostSize = maxHttpPostSize;
- }
- public Integer getAcceptors() {
- return this.acceptors;
- }
- public void setAcceptors(Integer acceptors) {
- this.acceptors = acceptors;
- }
- public Integer getSelectors() {
- return this.selectors;
- }
- public void setSelectors(Integer selectors) {
- this.selectors = selectors;
- }
- void customizeJetty(final ServerProperties serverProperties,
- JettyEmbeddedServletContainerFactory factory) {
- factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
- if (this.acceptors != null) {
- factory.setAcceptors(this.acceptors);
- }
- if (this.selectors != null) {
- factory.setSelectors(this.selectors);
- }
- if (serverProperties.getMaxHttpHeaderSize() > 0) {
- customizeMaxHttpHeaderSize(factory,
- serverProperties.getMaxHttpHeaderSize());
- }
- if (this.maxHttpPostSize > 0) {
- customizeMaxHttpPostSize(factory, this.maxHttpPostSize);
- }
- if (serverProperties.getConnectionTimeout() != null) {
- customizeConnectionTimeout(factory,
- serverProperties.getConnectionTimeout());
- }
- }
- private void customizeConnectionTimeout(
- JettyEmbeddedServletContainerFactory factory,
- final int connectionTimeout) {
- factory.addServerCustomizers(new JettyServerCustomizer() {
- @Override
- public void customize(Server server) {
- for (org.eclipse.jetty.server.Connector connector : server
- .getConnectors()) {
- if (connector instanceof AbstractConnector) {
- ((AbstractConnector) connector)
- .setIdleTimeout(connectionTimeout);
- }
- }
- }
- });
- }
- private void customizeMaxHttpHeaderSize(
- JettyEmbeddedServletContainerFactory factory,
- final int maxHttpHeaderSize) {
- factory.addServerCustomizers(new JettyServerCustomizer() {
- @Override
- public void customize(Server server) {
- for (org.eclipse.jetty.server.Connector connector : server
- .getConnectors()) {
- try {
- for (ConnectionFactory connectionFactory : connector
- .getConnectionFactories()) {
- if (connectionFactory instanceof HttpConfiguration.ConnectionFactory) {
- customize(
- (HttpConfiguration.ConnectionFactory) connectionFactory);
- }
- }
- }
- catch (NoSuchMethodError ex) {
- customizeOnJetty8(connector, maxHttpHeaderSize);
- }
- }
- }
- private void customize(HttpConfiguration.ConnectionFactory factory) {
- HttpConfiguration configuration = factory.getHttpConfiguration();
- configuration.setRequestHeaderSize(maxHttpHeaderSize);
- configuration.setResponseHeaderSize(maxHttpHeaderSize);
- }
- private void customizeOnJetty8(
- org.eclipse.jetty.server.Connector connector,
- int maxHttpHeaderSize) {
- try {
- connector.getClass().getMethod("setRequestHeaderSize", int.class)
- .invoke(connector, maxHttpHeaderSize);
- connector.getClass().getMethod("setResponseHeaderSize", int.class)
- .invoke(connector, maxHttpHeaderSize);
- }
- catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
- });
- }
- private void customizeMaxHttpPostSize(
- JettyEmbeddedServletContainerFactory factory, final int maxHttpPostSize) {
- factory.addServerCustomizers(new JettyServerCustomizer() {
- @Override
- public void customize(Server server) {
- setHandlerMaxHttpPostSize(maxHttpPostSize, server.getHandlers());
- }
- private void setHandlerMaxHttpPostSize(int maxHttpPostSize,
- Handler... handlers) {
- for (Handler handler : handlers) {
- if (handler instanceof ContextHandler) {
- ((ContextHandler) handler)
- .setMaxFormContentSize(maxHttpPostSize);
- }
- else if (handler instanceof HandlerWrapper) {
- setHandlerMaxHttpPostSize(maxHttpPostSize,
- ((HandlerWrapper) handler).getHandler());
- }
- else if (handler instanceof HandlerCollection) {
- setHandlerMaxHttpPostSize(maxHttpPostSize,
- ((HandlerCollection) handler).getHandlers());
- }
- }
- }
- });
- }
- }
- public static class Undertow {
- /**
- * Maximum size in bytes of the HTTP post content.
- */
- private long maxHttpPostSize = 0; // bytes
- /**
- * Size of each buffer in bytes.
- */
- private Integer bufferSize;
- /**
- * Number of buffer per region.
- */
- @Deprecated
- private Integer buffersPerRegion;
- /**
- * Number of I/O threads to create for the worker.
- */
- private Integer ioThreads;
- /**
- * Number of worker threads.
- */
- private Integer workerThreads;
- /**
- * Allocate buffers outside the Java heap.
- */
- private Boolean directBuffers;
- private final Accesslog accesslog = new Accesslog();
- public long getMaxHttpPostSize() {
- return this.maxHttpPostSize;
- }
- public void setMaxHttpPostSize(long maxHttpPostSize) {
- this.maxHttpPostSize = maxHttpPostSize;
- }
- public Integer getBufferSize() {
- return this.bufferSize;
- }
- public void setBufferSize(Integer bufferSize) {
- this.bufferSize = bufferSize;
- }
- @DeprecatedConfigurationProperty(reason = "The property is not used by Undertow. See https://issues.jboss.org/browse/UNDERTOW-587 for details")
- public Integer getBuffersPerRegion() {
- return this.buffersPerRegion;
- }
- public void setBuffersPerRegion(Integer buffersPerRegion) {
- this.buffersPerRegion = buffersPerRegion;
- }
- public Integer getIoThreads() {
- return this.ioThreads;
- }
- public void setIoThreads(Integer ioThreads) {
- this.ioThreads = ioThreads;
- }
- public Integer getWorkerThreads() {
- return this.workerThreads;
- }
- public void setWorkerThreads(Integer workerThreads) {
- this.workerThreads = workerThreads;
- }
- public Boolean getDirectBuffers() {
- return this.directBuffers;
- }
- public void setDirectBuffers(Boolean directBuffers) {
- this.directBuffers = directBuffers;
- }
- public Accesslog getAccesslog() {
- return this.accesslog;
- }
- void customizeUndertow(final ServerProperties serverProperties,
- UndertowEmbeddedServletContainerFactory factory) {
- if (this.bufferSize != null) {
- factory.setBufferSize(this.bufferSize);
- }
- if (this.ioThreads != null) {
- factory.setIoThreads(this.ioThreads);
- }
- if (this.workerThreads != null) {
- factory.setWorkerThreads(this.workerThreads);
- }
- if (this.directBuffers != null) {
- factory.setDirectBuffers(this.directBuffers);
- }
- if (this.accesslog.enabled != null) {
- factory.setAccessLogEnabled(this.accesslog.enabled);
- }
- factory.setAccessLogDirectory(this.accesslog.dir);
- factory.setAccessLogPattern(this.accesslog.pattern);
- factory.setAccessLogPrefix(this.accesslog.prefix);
- factory.setAccessLogSuffix(this.accesslog.suffix);
- factory.setAccessLogRotate(this.accesslog.rotate);
- factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
- if (serverProperties.getMaxHttpHeaderSize() > 0) {
- customizeMaxHttpHeaderSize(factory,
- serverProperties.getMaxHttpHeaderSize());
- }
- if (this.maxHttpPostSize > 0) {
- customizeMaxHttpPostSize(factory, this.maxHttpPostSize);
- }
- if (serverProperties.getConnectionTimeout() != null) {
- customizeConnectionTimeout(factory,
- serverProperties.getConnectionTimeout());
- }
- }
- private void customizeConnectionTimeout(
- UndertowEmbeddedServletContainerFactory factory,
- final int connectionTimeout) {
- factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
- @Override
- public void customize(Builder builder) {
- builder.setSocketOption(UndertowOptions.NO_REQUEST_TIMEOUT,
- connectionTimeout);
- }
- });
- }
- private void customizeMaxHttpHeaderSize(
- UndertowEmbeddedServletContainerFactory factory,
- final int maxHttpHeaderSize) {
- factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
- @Override
- public void customize(Builder builder) {
- builder.setServerOption(UndertowOptions.MAX_HEADER_SIZE,
- maxHttpHeaderSize);
- }
- });
- }
- private void customizeMaxHttpPostSize(
- UndertowEmbeddedServletContainerFactory factory,
- final long maxHttpPostSize) {
- factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {
- @Override
- public void customize(Builder builder) {
- builder.setServerOption(UndertowOptions.MAX_ENTITY_SIZE,
- maxHttpPostSize);
- }
- });
- }
- public static class Accesslog {
- /**
- * Enable access log.
- */
- private Boolean enabled;
- /**
- * Format pattern for access logs.
- */
- private String pattern = "common";
- /**
- * Log file name prefix.
- */
- protected String prefix = "access_log.";
- /**
- * Log file name suffix.
- */
- private String suffix = "log";
- /**
- * Undertow access log directory.
- */
- private File dir = new File("logs");
- /**
- * Enable access log rotation.
- */
- private boolean rotate = true;
- public Boolean getEnabled() {
- return this.enabled;
- }
- public void setEnabled(Boolean enabled) {
- this.enabled = enabled;
- }
- public String getPattern() {
- return this.pattern;
- }
- public void setPattern(String pattern) {
- this.pattern = pattern;
- }
- public String getPrefix() {
- return this.prefix;
- }
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
- public String getSuffix() {
- return this.suffix;
- }
- public void setSuffix(String suffix) {
- this.suffix = suffix;
- }
- public File getDir() {
- return this.dir;
- }
- public void setDir(File dir) {
- this.dir = dir;
- }
- public boolean isRotate() {
- return this.rotate;
- }
- public void setRotate(boolean rotate) {
- this.rotate = rotate;
- }
- }
- }
- /**
- * {@link ServletContextInitializer} to apply appropriate parts of the {@link Session}
- * configuration.
- */
- private static class SessionConfiguringInitializer
- implements ServletContextInitializer {
- private final Session session;
- SessionConfiguringInitializer(Session session) {
- this.session = session;
- }
- @Override
- public void onStartup(ServletContext servletContext) throws ServletException {
- if (this.session.getTrackingModes() != null) {
- servletContext.setSessionTrackingModes(this.session.getTrackingModes());
- }
- configureSessionCookie(servletContext.getSessionCookieConfig());
- }
- private void configureSessionCookie(SessionCookieConfig config) {
- Cookie cookie = this.session.getCookie();
- if (cookie.getName() != null) {
- config.setName(cookie.getName());
- }
- if (cookie.getDomain() != null) {
- config.setDomain(cookie.getDomain());
- }
- if (cookie.getPath() != null) {
- config.setPath(cookie.getPath());
- }
- if (cookie.getComment() != null) {
- config.setComment(cookie.getComment());
- }
- if (cookie.getHttpOnly() != null) {
- config.setHttpOnly(cookie.getHttpOnly());
- }
- if (cookie.getSecure() != null) {
- config.setSecure(cookie.getSecure());
- }
- if (cookie.getMaxAge() != null) {
- config.setMaxAge(cookie.getMaxAge());
- }
- }
- }
- }
在这个类里我们可以找到customizeTomcat方法,大家自行看看喽,类图如下:
Spring中的BeanPostProcessor的更多相关文章
- Spring中的BeanPostProcessor详解
Spring中的BeanPostProcessor详解 概述 BeanPostProcessor也称为Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初 ...
- 谈谈Spring中的BeanPostProcessor接口
一.前言 这几天正在复习Spring的相关内容,在了解bean的生命周期的时候,发现其中涉及到一个特殊的接口--BeanPostProcessor接口.由于网上没有找到比较好的博客,所有最后花了好 ...
- Spring中的BeanPostProcessor和BeanFactoryPostProcessor
BeanPostProcessor BeanFactoryPostProcessor 标准ioc容器初始化之后的后置处理器 BeanDefintionRegisterPostProcessor 在所有 ...
- Spring中BeanPostProcessor
Spring中BeanPostProcessor 前言: 本文旨在介绍Spring动态配置数据源的方式,即对一个DataSource的配置诸如jdbcUrl,user,password,driverC ...
- spring(三):spring中BeanPostProcessor的使用
spring中实现BeanPostProcessor的后置处理器 ApplicationContextAwareProcessor 进入该实现类内部 可以看到:该类帮我们组建IOC容器,判断我们的be ...
- Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- 通过BeanPostProcessor理解Spring中Bean的生命周期
通过BeanPostProcessor理解Spring中Bean的生命周期及AOP原理 Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProces ...
- Spring点滴十一:Spring中BeanFactoryPostProcessor和BeanPostProcessor区别
Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点.两个接口从名字看起来很相似,但是作用及使用场景却不同 ...
- Spring中的后置处理器BeanPostProcessor讲解
Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor.BeanFactoryPostProcessor.BeanValidationPostPr ...
随机推荐
- LA 3708 && POJ 3154 Graveyard (思维)
题意:在周长为10000的圆上等距分布着n个雕塑,现在又加入m个,现在让m+n个等距分布,那就得移动一些原有的雕塑,问你移动的最少总距离是多少. 析:首先我们可以知道,至少有一个雕塑是可以不用移动的, ...
- 1) Apache Maven 's README.txt
Apache Maven What is it? ----------- Maven is a software project management and comprehension tool. ...
- HDU 3455 Leap Frog 2016-09-12 16:34 43人阅读 评论(0) 收藏
Leap Frog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- android Qzone的App热补丁热修复技术
转自:https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731 ...
- .Net socket服务器编程之为何也高效
说到Socket编程,肯定大部分人举手c,c++.可惜现在已没有机会去追随并达到写服务器的水平,所以将就下还是考虑c#版的Socket服务器吧. 经过一番查询,试用.一些数据和事实还是浮出水面,同时对 ...
- delphi 动态加载dll
引入文件 DLL比较复杂时,可以为它的声明专门创建一个引入单元,这会使该DLL变得更加容易维护和查看.引入单元的格式如下: unit MyDllImport; {Import unit for MyD ...
- SpringBoot tomcat
该文的前提是已经可以在控制台运行成功,有些时候想放在tomcat里运行 大致分为如下几步 1.配置文件更改 <dependency> <groupId>org.springfr ...
- PLSQL(PL/SQL)集成Team Foundation Server (TFS),实现数据库代码的版本管理
PL/SQL是面向Oralcle数据库的集成开发环境,是众多Oracle数据库开发人员的主要工具.由于PL/SQL(百度百科)不仅是一种SQL语言,更是一种过程编程语言,在项目实施过程中,会积累大量除 ...
- linux系统编程之进程(一):进程与程序
本节目标: 什么是程序 什么是进程 进程数据结构 进程与程序区别与联系 一,什么是程序? 程序是完成特定任务的一系列指令集合 二,什么是进程? 从用户的角度来看进程是程序的一次动态执行过程 从操作系统 ...
- C# 使用ftp下载一个文件夹下的所有文件,包括子目录文件夹
这篇博客给大家补充一个方法,就是得到一个目录下的所有文件名称.在前端调用,大家写一个递归去遍历就可以了,我在这里就不在写了.具体ftp下载的方法在我的另一篇博客里有,需要的可以去看一下. /// &l ...