您的位置:首页 > 运维架构 > Tomcat

spring-boot 自定义内置tomcat设置

2017-02-06 00:00 302 查看
随着spring-boot越来越多的应用到web项目的开发当中,我们公司的项目也一一转入了spring-boot的开发和运行环境中,当然只要用了就会有小问题。

前一段时间tomcat发布了一个关于信息泄露的漏洞(https://www.oschina.net/news/79943/cve-2016-8745-apache-tomcat-information-disclosure),其中需要将原本的nio http连接器改成nio2的,但是找了很多好像没有关于这些的配置,索性就自己翻了翻代码找了找,看到了一些不错的小东西,拿来分享一下。第一次写博客,语言表达能力有不强所以还望见谅。

直接核心代码:

package com.shineyue;

import java.io.File;

import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.AbstractProtocol;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.util.StringUtils;

public class ShineyueTomcatEmbeddedServletContainerFactory extends
TomcatEmbeddedServletContainerFactory {
public ShineyueTomcatEmbeddedServletContainerFactory() {
super();
}
public ShineyueTomcatEmbeddedServletContainerFactory(int port) {
super(port);
}
public ShineyueTomcatEmbeddedServletContainerFactory(String contextPath, int port) {
super(contextPath, port);
}
@Override
public EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector("org.apache.coyote.http11.Http11Nio2Protocol");//把之前的nio改成了nio2
tomcat.getService().addConnector(connector);
customizeConnector(connector);
customizePrivateConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
tomcat.getEngine().setBackgroundProcessorDelay(-1);
for (Connector additionalConnector : super.getAdditionalTomcatConnectors()) {
//注释掉加载自定义tomcat实例的代码
//tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatEmbeddedServletContainer(tomcat);
}
protected void customizePrivateConnector(Connector connector) {
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
customizePrivateProtocol((AbstractProtocol<?>) connector.getProtocolHandler());
}
}
private void customizePrivateProtocol(AbstractProtocol<?> protocol) {
protocol.setMaxConnections(500);
//在这里随便写自定义的配置

}
}

类TomcatEmbeddedServletContainerFactory是spring创建内置tomcat对象的工厂类,其中定义了关于内置tomcat的所有自动配置属性和可以自定义的属性,在没有注入自定义的tomcat实例时,spring会在内部只启动默认的实例,但是我们注入自定义的tomcat对象之后,其实就是同时启动了2个tomcat实例(占用2个端口),看不懂没关系看下面代码:

@Bean
public EmbeddedServletContainerFactory servletContainer1() {
System.out.println("13231");
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.setUriEncoding(Charset.forName("UTF-8"));
tomcat.addAdditionalTomcatConnectors(createNioConnector1());
return tomcat;
}
public Connector createNioConnector1(){
Connector connector=new Connector("org.apache.coyote.http11.Http11Nio2Protocol");
Http11Nio2Protocol protocol = (Http11Nio2Protocol) connector.getProtocolHandler();
protocol.setConnectionTimeout(200);
protocol.setMaxThreads(200);
protocol.setMaxConnections(1000);
connector.setScheme("http");
connector.setPort(8015);//自定义的
connector.setRedirectPort(8443);

return connector;
}

在带有@Configuration的类中有如下代码,这段代码为在spring启动时注入了一个自定义的tomcat实例,这样启动spring-boot后会有2个监听端口,既是8015和在配置文件中定义的端口。

所以我们修改
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();


ShineyueTomcatEmbeddedServletContainerFactory tomcat = new ShineyueTomcatEmbeddedServletContainerFactory();

将其换成我们重新修改过的类,这样代码就成了这个样子:
//@Bean
public EmbeddedServletContainerFactory servletContainer() {
ShineyueTomcatEmbeddedServletContainerFactory tomcat = new ShineyueTomcatEmbeddedServletContainerFactory();
tomcat.setUriEncoding(Charset.forName("UTF-8"));
tomcat.addAdditionalTomcatConnectors(createNioConnector());
return tomcat;
}

我们可以在ShineyueTomcatEmbeddedServletContainerFactory 类中随意修改自己需要的tomcat配置,包括将nio改为nio2。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java Spring Boot Tomcat nio web