1. 测试案例
1.1 引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.64</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.64</version>
</dependency>
1.2 Servlet处理类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("hello tomcat");
}
}
1.3 启动类
public class Main {
public static void main(String[] args) throws LifecycleException {
//自己写Tomcat的启动源码
Tomcat tomcat = new Tomcat();
tomcat.setPort(8888);
tomcat.setHostname("localhost");
tomcat.setBaseDir(".");
Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");
//给Tomcat里面添加一个Servlet
Wrapper hello = tomcat.addServlet("/boot", "hello", new HelloServlet());
hello.addMapping("/66"); //指定处理的请求
tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制
tomcat.getServer().await(); //服务器等待
}
}
直接运行main方法,在浏览器中输入 http://localhost:8888/boot/66 ,输出为:
hello tomcat
以上只是一个Tomcat
的启动并使用HelloServlet
处理一个请求的案例。下面我们结合SpringMVC,看如何优雅的启动。
2. 嵌入式Tomcat启动SpringMVC
2.1 最简单的方法
public class Main {
public static void main(String[] args) throws LifecycleException {
//自己写Tomcat的启动源码
Tomcat tomcat = new Tomcat();
tomcat.setPort(8888);
tomcat.setHostname("localhost");
tomcat.setBaseDir(".");
Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");
//自己创建 DispatcherServlet 对象,并且创建ioc容器,DispatcherServlet里面有ioc容器
DispatcherServlet servlet = new DispatcherServlet();
Wrapper hello = tomcat.addServlet("/boot", "hello", servlet);
tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制
tomcat.getServer().await(); //服务器等待
}
}
当然,如果使用这种方法启动,需要自己往容器中注入DispatcherServlet
的各种初始化(九大组件等),所以这种方式比较麻烦,我们不采用这种方式。
2.2 Tomcat的SPI机制启动
利用tomcat的SPI启动机制,SPI机制下 QuickAppStarter
生效创建 ioc容器配置DispatcherServlet
等各种组件。可以参考Spring5源码14-SpringMVC入口及启动流程。代码如下:
Main.java:
public class Main {
public static void main(String[] args) throws LifecycleException {
//自己写Tomcat的启动源码
Tomcat tomcat = new Tomcat();
tomcat.setPort(8888);
tomcat.setHostname("localhost");
tomcat.setBaseDir(".");
Context context = tomcat.addWebapp("/boot", System.getProperty("user.dir") + "/src/main");
tomcat.start(); //启动tomcat 注解版MVC利用Tomcat SPI机制
tomcat.getServer().await(); //服务器等待
}
}
QuickAppStarter类:
/**
* 最快速的整合注解版SpringMVC和Spring的
*/
public class QuickAppStarter extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override //根容器的配置(Spring的配置文件===Spring的配置类)
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{SpringConfig.class};
}
@Override //web容器的配置(SpringMVC的配置文件===SpringMVC的配置类)
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{SpringMVCConfig.class};
}
@Override //Servlet的映射,DispatcherServlet的映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
// super.customizeRegistration(registration);
// registration.addMapping("");//
}
}
启动后,在浏览器访问http://localhost:8888/boot/hello66 ,输出为: