【spring boot2】第8篇:spring boot 中的 servlet 容器及如何使用war包部署

news/2024/6/28 20:24:16

嵌入式 servlet 容器

在 spring boot 之前的web开发,我们都是把我们的应用部署到 Tomcat 等servelt容器,这些容器一般都会在我们的应用服务器上安装好环境,但是 spring boot 中并不需要外部应用服务器安装这些servlet容器,spring boot自带了嵌入式的servlet容器。

如何修改和定制嵌入式servlet容器

  • 在application.yaml文件中配置修改
#修改服务端口号
server.port=8081
#配置统一请求路径
server.context‐path=/crud#配置tomcat相关
server.tomcat.uri‐encoding=UTF‐8

这些配置相关的属性都定义在org.springframework.boot.autoconfigure.web.ServerProperties类中

  • 编写一个嵌入式的servlet容器的定制器来修改相关的配置
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {@Overridepublic void customize(ConfigurableServletWebServerFactory server) {server.setPort(9000);}
}
  • 直接定制具体的servlet容器配置,比如 tomcat 容器
@Configuration
public class ApplicationConfig implements WebMvcConfigurer {@Beanpublic ConfigurableServletWebServerFactory configurableServletWebServerFactory() {TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();factory.setPort(8585);return factory;}
}

注册 Servlet、Filter、Listener

spring boot默认是以 jar 包的方式启动嵌入式的 servlet 容器来启动web应用,应用中并没有 web.xml 文件,我们注册 servlet, filter, 和 listener 三大组件可以使用以下方式

  • 利用ServletRegistrationBean注册 servlet

    • 定义自己的 servlet
    public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {resp.getWriter().print("servlet doGet");}
    }
    • 给容器中注册自己的 servlet
    @Configuration
    public class ApplicationConfig implements WebMvcConfigurer {@Beanpublic ServletRegistrationBean myServlet() {ServletRegistrationBean servletRegistrationBean =new ServletRegistrationBean(new MyServlet(), "/hello/servlet");return servletRegistrationBean;}
    }
  • 利用FilterRegistrationBean注册 filter

    • 定义 filter`
    public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("do myFilter");chain.doFilter(request, response);}
    }
    • 容器中注册 filter
    @Configuration
    public class ApplicationConfig implements WebMvcConfigurer {@Beanpublic FilterRegistrationBean myFilter() {FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//注册自己的 filterfilterRegistrationBean.setFilter(new MyFilter());//注册拦截路径filterRegistrationBean.setUrlPatterns(Arrays.asList("/hello", "/hello/servlet"));return filterRegistrationBean;}
    }

    访问 "/hello", "/hello/servlet"请求时拦截器就会起作用。

  • 利用ServletListenerRegistrationBean注册 listener

    • 定义一个listener
    public class MyListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("contextInitialized ... web应用启动");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("contextDestroyed ... web应用销毁");}
    }
    • 容器中注册listener
    
    @Configuration
    public class ApplicationConfig implements WebMvcConfigurer {@Beanpublic ServletListenerRegistrationBean myListener() {ServletListenerRegistrationBean<MyListener> listenerRegistrationBean =new ServletListenerRegistrationBean(new MyListener());return listenerRegistrationBean;}
    }

切换其他 servlet 容器

spring boot 中默认使用的是 tomcat 容器,那么如何切换使用其他容器呢,比如 jetty。那么如何切换成其他的呢?只需要修改 pom.xml 文件

<!‐‐ 引入web模块 ‐‐> 
<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><!‐‐引入其他的servlet容器‐‐> 
<dependency><artifactId>spring‐boot‐starter‐jetty</artifactId><groupId>org.springframework.boot</groupId></dependency>

使用外部 servlet 容器

部署项目的服务器安装 servlet 容器,比如 tomcat、jetty 容器,然后项目打成 war 包的形式进行部署
如何创建一个 war 包启动的 spring boot 项目呢?

  1. 创建一个war打包形式的web项目,其目录结构如下

图片描述

  1. 修改 pom.xml 文件

    • 修改打包方式

      pom.xml 文件中的打包方式设置成 war 即可,            ```<packaging>war</packaging>```
    • 修改嵌入的 servlet 容器

      <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope>
      </dependency>
  2. 编写一个类继承 SpringBootServletInitializer
public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(SpringBootWarApplication.class);}
}

使用外部 servlet 容器原理

jar包和war的启动过程

  1. jar包: 执行spring boot 主类的main方法,启动ioc容器,然后创建嵌入式的servlet容器
  2. war包: 启动tomcat服务器,服务器启动spring boot应用,通过SpringBootServletInitializer实现,启动ioc容器

spring boot使用外部servlet过程

servlet3.0标准中规定

  • web应用启动会创建当前web应用里面每一个jar包里面ServletContainerInitializer类型的实例
  • ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下,有一个名为javax.servlet.ServletContainerInitializer的文件,文件内容就是ServletContainerInitializer实现类的全类名
  • 使用@HandlesTypes注解在应用启动的时候加载我们需要的类

spring boot使用war启动原理

  • 重写SpringBootServletInitializerconfigure(SpringApplicationBuilder application)方法,调用SpringApplicationBuildersources(Class<?>... sources)方法
  • 启动原理

    • Servlet3.0标准ServletContainerInitializer扫描所有jar包中META- INF/services/javax.servlet.ServletContainerInitializer文件指定的类并加载
    • 加载spring web包下的org.springframework.web.SpringServletContainerInitializer
    • 扫描@HandleType(WebApplicationInitializer)`,即扫描WebApplicationInitializer的所有实现类
    • 加载SpringBootServletInitializer并运行onStartup方法
    • 加载@SpringBootApplication主类,启动容器

http://lihuaxi.xjx100.cn/news/236267.html

相关文章

ubuntu安装deepin terminal 终端

1. 依赖库 sudo apt-get install libatk1.0-0 libc6 libcairo-gobject2 libcairo2 libfontconfig1 libfreetype6 libgdk-pixbuf2.0-0 libgee-0.8-2 libglib2.0-0 libgnutls30 libgtk-3-0 libjson-glib-1.0-0 libpango-1.0-0 libpangocairo-1.0-0 libsecret-1-0 libvte-2.91-0…

三星android获取root权限,三星G9250(S6 Edge公开版全网通 Android 5.1)获取ROOT权限详解教程...

伴随着安卓刷机越来越流行&#xff0c;很多安卓用户都喜欢上了这种可以自定个性系统的行为&#xff0c;那么三星G9250(S6 Edge公开版全网通 Android 5.1)怎么获取ROOT权限?三星G9250(S6 Edge公开版全网通 Android 5.1)一ROOT过程如何操作呢?奇兔小编在此大家说一说一键ROOT的…

让织梦内容页arclist标签的当前文章标题加亮显示

很多人在用织梦做站的时候&#xff0c;会用到在当前栏目页面&#xff0c;给当前栏目标题使用指定样式如标题加亮&#xff0c;或者放个背景图。这是一个很常用和实用的功能&#xff0c;比如在导航页面&#xff0c;标识当前在浏览哪个栏目。如下图&#xff1a; 但是有些时候&…

Mob之社会化分享集成ShareSDK

接着上篇顺便分享一篇自己使用 ShareSDK 的笔记&#xff0c;上篇我们集成了 SMSSDK 完成了短信接收验证码的功能&#xff0c;请参考Mob 之 短信验证集成 SMSSDK&#xff0c;如何在项目已经集成 SMSSDK 的情况下集成 ShareSDk 到项目中&#xff0c;上一篇中我们集成 SMSSDK 使用…

正则:匹配一个汉字姓名

//汉字姓名正则var reg/^[\u4e00-\u9fa5]{2,}(\.[\u4e00-\u9fa5])?$/console.log(reg.test(张卫健.爱新觉罗))console.log(reg.test(兔子)) 复制代码

安装Android SDK需要选择哪些,开始为Android开发,我应该选择安装哪些SDK?

我开始将我的开发人员技能扩展到Android开发.我安装了所有的工具和配置,每件事看起来都很棒,作为默认设置,我安装了3.2 SDK,但是没有太多的文档在那个,2.x SDK上的模式是什么.它是否像IOS,android有一个良好的向后可计算性&#xff1f;我可以继续使用3.x并依靠它(使用2.x SDK中…

Drill storage plugin实现原理分析

Drill Storage Plugin介绍 Drill是一个交互式SQL查询引擎&#xff0c;官方默认支持的数据源有hive、hbase、kafka、kudu、mongo、opentsdb、jdbc等&#xff0c;其中jdbc storage plugin可以覆盖所有支持jdbc协议的数据源&#xff0c;如&#xff1a;mysql、oracle等关系型数据库…

学习成长就到鸿蒙思维,庆国庆,迎中秋,鸿蒙教育享双节99元开启思维之旅!!...

原标题&#xff1a;庆国庆&#xff0c;迎中秋&#xff0c;鸿蒙教育享双节99元开启思维之旅&#xff01;&#xff01;庆国庆&#xff0c;迎中秋&#xff0c;鸿蒙教育享双节99元开启思维之旅&#xff01;&#xff01;鸿蒙口才&#xff0b;绘画课推出99元体验课程&#xff01;学1科…