随着spring-boot愈来愈多的应用到web项目的开发当中,咱们公司的项目也一一转入了spring-boot的开发和运行环境中,固然只要用了就会有小问题。java
前一段时间tomcat发布了一个关于信息泄露的漏洞(https://www.oschina.net/news/79943/cve-2016-8745-apache-tomcat-information-disclosure),其中须要将本来的nio http链接器改为nio2的,可是找了不少好像没有关于这些的配置,索性就本身翻了翻代码找了找,看到了一些不错的小东西,拿来分享一下。第一次写博客,语言表达能力有不强因此还望见谅。web
直接核心代码:spring
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个端口),看不懂不要紧看下面代码:apache
@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和在配置文件中定义的端口。tomcat
因此咱们修改ide
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
为spring-boot
ShineyueTomcatEmbeddedServletContainerFactory tomcat = new ShineyueTomcatEmbeddedServletContainerFactory();
将其换成咱们从新修改过的类,这样代码就成了这个样子:.net
//@Bean public EmbeddedServletContainerFactory servletContainer() { ShineyueTomcatEmbeddedServletContainerFactory tomcat = new ShineyueTomcatEmbeddedServletContainerFactory(); tomcat.setUriEncoding(Charset.forName("UTF-8")); tomcat.addAdditionalTomcatConnectors(createNioConnector()); return tomcat; }
咱们能够在ShineyueTomcatEmbeddedServletContainerFactory 类中随意修改本身须要的tomcat配置,包括将nio改成nio2。code