最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

day04-实现SpringBoot底层机制

来源:博客园

实现SpringBoot底层机制

Tomcat底层启动分析+Spring容器初始化+Tomcat关联Spring容器

1.任务1-创建Tomcat,并启动

(1)创建一个Maven项目,修改pom.xml文件:我们需要自己创建Tomcat对象,因此在引入的场景启动器中排除SpringBoot内嵌的Tomcat,并引入tomcat依赖库

    spring-boot-starter-parent    org.springframework.boot    2.5.3                org.springframework.boot        spring-boot-starter-web                                            org.springframework.boot                spring-boot-starter-tomcat                                        org.apache.tomcat.embed        tomcat-embed-core        8.5.75    

(2)创建LiSpringApplication.java


(资料图)

package com.li.lispringboot;import org.apache.catalina.startup.Tomcat;/** * @author 李 * @version 1.0 */public class LiSpringApplication {    //创建tomcat对象,并关联spring容器,然后启动tomcat    public static void run() {        try {            //创建tomcat对象            Tomcat tomcat = new Tomcat();            //设置默认端口-9090            tomcat.setPort(9090);            //启动,就会在指定端口监听            tomcat.start();            //等待请求接入            System.out.println("======9090端口等待请求接入======");            tomcat.getServer().await();        } catch (Exception e) {            e.printStackTrace();        }    }}

(3)LiMainApp

package com.li.lispringboot;/** * @author 李 * @version 1.0 */public class LiMainApp {    public static void main(String[] args) {        //启动LiSpringBoot项目/程序        LiSpringApplication.run();    }}

(4)测试启动main方法,后台输出如下:

打开浏览器,访问9090端口,页面一片空白,因为这时候还没有接入其他组件。

2.任务2-创建Spring容器

(1)创建Monster.java,做一个测试bean

package com.li.lispringboot.bean;/** * @author 李 * @version 1.0 */public class Monster {}

(2)创建HelloController.java,做一个测试Controller

package com.li.lispringboot.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * @author 李 * @version 1.0 */@RestControllerpublic class HelloController {    @RequestMapping("/hello")    public String Hello() {        return "Hello,I"m HelloController!";    }}

(3)创建LiConfig.java,作为Spring的配置文件

package com.li.lispringboot.config;import com.li.lispringboot.bean.Monster;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/** * @author 李 * @version 1.0 * 配置类-作为Spring的配置文件 * 这里有一个问题,容器怎么知道要扫描哪些包? */@Configuration@ComponentScan("com.li.lispringboot")//指定要配置类扫描哪些包public class LiConfig {    //注入Bean-Monster对象到Spring容器    @Bean    public Monster monster() {        return new Monster();    }}

(4)LiWebApplicationInitializer.java

package com.li.lispringboot;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;/** * @author 李 * @version 1.0 * LiWebApplicationInitializer容器初始化类的任务: * 1.创建spring容器 * 2.加载/关联spring容器的配置-按照注解方式 * 3.完成spring容器配置的bean的创建,依赖注入 * 4.创建前端控制器(DispatcherServlet),让其持有spring容器 * 5.这的onStartup()方法是tomcat来调用,并把ServletContext对象传入 */public class LiWebApplicationInitializer implements WebApplicationInitializer {    @Override    public void onStartup(ServletContext servletContext) throws ServletException {        System.out.println("onStartup ...");        //加载-Spring Web Application Configuration        AnnotationConfigWebApplicationContext ac =                new AnnotationConfigWebApplicationContext();        //在ac中注册配置类LiConfig        ac.register(LiConfig.class);        ac.refresh();//完成bean的创建和配置        /*        创建注册非常重要的前端控制器-DispatchServlet        让 DispatchServlet持有spring容器-ac        这样就可以进行映射分发        */        DispatcherServlet dispatcherServlet = new DispatcherServlet(ac);        //返回ServletRegistration.Dynamic对象        ServletRegistration.Dynamic registration                = servletContext.addServlet("app", dispatcherServlet);        //设置前端控制器的加载顺序(这里设置为当tomcat启动时,就加载)        registration.setLoadOnStartup(1);        //设置前端控制器拦截所有请求,并进行分发处理        registration.addMapping("/");    }}

3.任务3-将Tomcat和Spring容器关联,并启动Spring容器

(1)修改LiSpringApplication,将tomcat和Spring容器关联

package com.li.lispringboot;import org.apache.catalina.startup.Tomcat;/** * @author 李 * @version 1.0 */public class LiSpringApplication {    //创建tomcat对象,并关联spring容器,然后启动tomcat    public static void run() {        try {            //创建tomcat对象            Tomcat tomcat = new Tomcat();            /*              1.让tomcat能够将请求转发到SpringWeb容器,因此需要关联              2."/liboot" 就是我们的项目的 application context,即原来配置tomcat时的项目名称              3."D:\\IDEA-workspace\\li-springboot" 指定项目的路径             */            tomcat.addWebapp("/liboot", "D:\\IDEA-workspace\\li-springboot");            //设置默认端口-9090            tomcat.setPort(9090);            //启动,就会在指定端口监听            tomcat.start();            //等待请求接入            System.out.println("======9090端口等待请求接入======");            tomcat.getServer().await();        } catch (Exception e) {            e.printStackTrace();        }    }}

(2)在LiMainApp.java中重新启动项目,在浏览器中访问测试Controller,访问成功:

3.1注意事项和细节

如果启动时报异常,如下:

严重: Servlet [jsp] in web application [/liboot] threw load() exception java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet

解决方案是:引入对应版本的 Jasper包即可。

    org.apache.tomcat    tomcat-jasper    8.5.75

关键词: