隨着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