十五、定制嵌入式servlet容器

Spring Boot支持内嵌的Tomcat, Jetty和Undertow服务器。多数开发者只需要使用合适的’Starter POM’来获取一个完全配置好的实例即可。

常见的Servlet容器设置可以通过Spring Environment属性进行配置。通常,你会把这些属性定义到application.properties文件中。 常见的服务器设置包括:

  • server.port - 进来的HTTP请求的监听端口号
  • server.address - 绑定的接口地址
  • server.sessionTimeout - session超时时间
    具体参考ServerProperties类。

编程方式的自定义

如果需要以编程的方式配置内嵌的servlet容器,你可以注册一个实现EmbeddedServletContainerCustomizer接口的Spring bean。EmbeddedServletContainerCustomizer提供对ConfigurableEmbeddedServletContainer的访问,ConfigurableEmbeddedServletContainer包含很多自定义的setter方法。

package com.lf.config;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;

/**
 * Created by LF on 2017/4/17.
 */
public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    @Override
    public void customize(ConfigurableEmbeddedServletContainer container) {
        container.setPort(8080);
    }
}

自定义ConfigurableEmbeddedServletContainer

如果上面的自定义手法过于受限,你可以自己注册TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory。

package com.lf.config;

import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

import java.util.concurrent.TimeUnit;

/**
 * Created by LF on 2017/4/17.
 */
@Configuration
public class WebConfig {
    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.setPort(9000);
        //,,,,,,,,,,,,,
        factory.setSessionTimeout(10, TimeUnit.MINUTES);
        factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html");
        return factory;
    }
}

改变HTTP端口

在一个单独的应用中,主HTTP端口默认为8080,但可以使用server.port设置(比如,在application.properties中或作为一个系统属性)。由于Environment值的宽松绑定,你也可以使用SERVER_PORT(比如,作为一个OS环境变)。

为了完全关闭HTTP端点,但仍创建一个WebApplicationContext,你可以设置server.port=-1(测试时可能有用)。

使用随机未分配的HTTP端口

想扫描一个未使用的端口(为了防止冲突使用OS本地端口)可以使用server.port=0。

发现运行时的HTTP端口

你可以通过日志输出或它的EmbeddedServletContainer的EmbeddedWebApplicationContext获取服务器正在运行的端口。获取和确认服务器已经初始化的最好方式是添加一个ApplicationListener类型的@Bean,然后当事件发布时将容器pull出来。

使用@WebIntegrationTests的一个有用实践是设置server.port=0,然后使用@Value注入实际的(’local’)端口。例如:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
@WebIntegrationTest("server.port:0")
public class CityRepositoryIntegrationTests {

    @Autowired
    EmbeddedWebApplicationContext server;

    @Value("${local.server.port}")
    int port;

    // ...

}

启用Tomcat的多连接器

你可以将一个org.apache.catalina.connector.Connector添加到TomcatEmbeddedServletContainerFactory,这就能够允许多连接器,比如HTTP和HTTPS连接器:

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
    tomcat.addAdditionalTomcatConnectors(createSslConnector());
    return tomcat;
}

private Connector createSslConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    try {
        File keystore = new ClassPathResource("keystore").getFile();
        File truststore = new ClassPathResource("keystore").getFile();
        connector.setScheme("https");
        connector.setSecure(true);
        connector.setPort(8443);
        protocol.setSSLEnabled(true);
        protocol.setKeystoreFile(keystore.getAbsolutePath());
        protocol.setKeystorePass("changeit");
        protocol.setTruststoreFile(truststore.getAbsolutePath());
        protocol.setTruststorePass("changeit");
        protocol.setKeyAlias("apitester");
        return connector;
    }
    catch (IOException ex) {
        throw new IllegalStateException("can't access keystore: [" + "keystore"
                + "] or truststore: [" + "keystore" + "]", ex);
    }
}

使用Tomcat7

Tomcat7可用于Spring Boot,但默认使用的是Tomcat8。如果不能使用Tomcat8(例如,你使用的是Java1.6),你需要改变classpath去引用Tomcat7。

如果正在使用starter pom和parent,你只需要改变Tomcat的version属性,比如,对于一个简单的webapp或service:


    7.0.59


    ...
    
        org.springframework.boot
        spring-boot-starter-web
    
    ...

你可能感兴趣的:(SpringBoot)