SpringBoot 修改服务器配置
配置文件方式方式修改, 实际修改的是 ServerProperties 文件中的值
- server.servlet.context-path=/crud
- server.port=8081
Java 代码方式修改. 通过实现
webServerFactoryCusomizer
接口来获取到达
ConfigurableServletWebServerFactory
的通道,
ConfigurableServletWebServerFactory
中提供了很多的方法用来修改服务器配置.
- @Component
- public class ServletHandler implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
- @Override
- public void customize(ConfigurableServletWebServerFactory factory) {
- factory.setPort(8083);
- }
- }
SpringBoot 使用原生 Web 组件
在之前的 Web 项目中, 我们会通过 Web.xml 来注册三大组件, 在 springboot 中我们通过提供的类注册三大组件
Servlet. 通过
ServletRegistrationBean
来注册一个 Servlet
- @Bean
- public ServletRegistrationBean myServlet(){
- ServletRegistrationBean registration = new ServletRegistrationBean(new MyServlet(),"/hello");
- return registration;
- }
Filter. 通过
FilterRegistrationBean
来祖册 Filter
- @Bean
- public FilterRegistrationBean myFilter(){
- FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
- filterRegistrationBean.setFilter(new MyFilter());
- filterRegistrationBean.setUrlPatterns(Arrays.asList("/hello"));
- return filterRegistrationBean ;
- }
Listener. 通过
ServletListenerRegistrationBean
来注册一个监听器
- @Bean
- public ServletListenerRegistrationBean myServletListener(){
- ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();
- registrationBean.setListener(new MyServletContextListener());
- return registrationBean ;
- }
Spring 使用其他服务器
SpringBoot 提供了三个服务器工厂, Tomcat,Jetty,Undertow, 默认使用了 Tomcat
使用 Jetty. 需要排除 Tomcat 依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Web</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- <groupId>org.springframework.boot</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <artifactId>spring-boot-starter-jetty</artifactId>
- <groupId>org.springframework.boot</groupId>
- </dependency>
使用 Undertow 服务器. 同 Jetty 一样
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-Web</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- <groupId>org.springframework.boot</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <artifactId>spring-boot-starter-undertow</artifactId>
- <groupId>org.springframework.boot</groupId>
- </dependency>
SpringBoot 服务器自动配置原理
Springboot 通过
WebServerInitializedEvent
来实现服务器自动配置, 通过这个类来加载一个 WebServer
- public abstract class WebServerInitializedEvent extends ApplicationEvent {
- protected WebServerInitializedEvent(WebServer webServer) {
- super(webServer);
- }
通过 WebServer 来创建固定的服务器.
- TomcatWebServer
- JettyWebServer
- NettyWebServer
- UndertowWebServer
- public interface WebServer {
- void start() throws WebServerException;
- void stop() throws WebServerException;
- int getPort();
- }
SpringBoot 启动 Tomcat 服务器的过程
SpringBoot 启动方法
SpringApplication.run(DemoApplication.class, args)
调用
SpringAllication.run
方法返回了
ConfigurableApplicationContext
对象
- public ConfigurableApplicationContext run(String... args) {
- context = this.createApplicationContext();// 创建了一个 Application 对象
- this.refreshContext(context);// 刷新 ApplicationContext
- protected ConfigurableApplicationContext createApplicationContext() {
- Class<?> contextClass = this.applicationContextClass;
- if (contextClass == null) {
- try {
- switch(this.webApplicationType) {
- case SERVLET:
- contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
- break;
- case REACTIVE:
- contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
- break;
- default:
- contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
- }
- } catch (ClassNotFoundException var3) {
- throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
- }
- }
- return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
- }
创建了
AnnotationConfigReactiveWebServerApplicationContext
这个类最终实现了
- AbstractApplicationContext
- private void refreshContext(ConfigurableApplicationContext context) {
- this.refresh(context);
- if (this.registerShutdownHook) {
- try {
- context.registerShutdownHook();
- } catch (AccessControlException var3) {
- }
- }
- }
- protected void refresh(ApplicationContext applicationContext) {
- Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
- ((AbstractApplicationContext)applicationContext).refresh();
- }
- public void refresh() throws BeansException, IllegalStateException {
- synchronized(this.startupShutdownMonitor) {
- this.prepareRefresh();
- ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
- this.prepareBeanFactory(beanFactory);
- try {
- this.postProcessBeanFactory(beanFactory);
- this.invokeBeanFactoryPostProcessors(beanFactory);
- this.registerBeanPostProcessors(beanFactory);
- this.initMessageSource();
- this.initApplicationEventMulticaster();
- // 调用子类的刷新方法, 最终调用的是创建 ApplicationContext 容器中所选择的容器即 ServletWebServerApplicationContext 类中的方法
- this.onRefresh();
- this.registerListeners();
- this.finishBeanFactoryInitialization(beanFactory);
- this.finishRefresh();
- } catch (BeansException var9) {
- if (this.logger.isWarnEnabled()) {
- this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt:" + var9);
- }
- this.destroyBeans();
- this.cancelRefresh(var9);
- throw var9;
- } finally {
- this.resetCommonCaches();
- }
- }
- }
- protected void onRefresh() {
- super.onRefresh();
- try {
- // 创建了 Web 容器
- this.createWebServer();
- } catch (Throwable var2) {
- throw new ApplicationContextException("Unable to start web server", var2);
- }
- }
- private void createWebServer() {
- WebServer webServer = this.webServer;
- ServletContext servletContext = this.getServletContext();
- // 当容器中没有服务器的时候
- if (webServer == null && servletContext == null) {
- // 创建一个 Web 服务器,
- ServletWebServerFactory factory = this.getWebServerFactory();
- this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
- } else if (servletContext != null) {
- try {
- this.getSelfInitializer().onStartup(servletContext);
- } catch (ServletException var4) {
- throw new ApplicationContextException("Cannot initialize servlet context", var4);
- }
- }
- this.initPropertySources();
- }
- protected ServletWebServerFactory getWebServerFactory() {
- // 获取了容器中 ServletWebServerFactory 类型的容器
- String[] beanNames = this.getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
- if (beanNames.length == 0) {
- throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.");
- } else if (beanNames.length> 1) {
- throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans :" + StringUtils.arrayToCommaDelimitedString(beanNames));
- } else {
- // 创建了 Web 服务器
- return (ServletWebServerFactory)this.getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
- }
- }
通过
this.getWebServerFactory
方法创建了 Web 服务器, 通过
this.getBeanFactory()
获取了容器中所存在的类型为
ServletWebServerFactory
类型的容器, 然后获取 bean 创建了 Tomcat 对象
来源: https://www.cnblogs.com/onlyzuo/p/12349300.html