{"id":15211371,"url":"https://github.com/ifan112/demo-spring-webmvc","last_synced_at":"2026-03-16T05:11:27.169Z","repository":{"id":101766572,"uuid":"172004516","full_name":"ifan112/demo-spring-webmvc","owner":"ifan112","description":"spring-webmvc学习项目","archived":false,"fork":false,"pushed_at":"2019-03-01T07:21:45.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-12-25T17:11:09.924Z","etag":null,"topics":["java","spring","spring-webmvc"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ifan112.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-22T06:09:36.000Z","updated_at":"2019-03-01T07:21:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"eab84c7c-2057-4d17-b007-230f41aea88c","html_url":"https://github.com/ifan112/demo-spring-webmvc","commit_stats":{"total_commits":5,"total_committers":2,"mean_commits":2.5,"dds":"0.19999999999999996","last_synced_commit":"775a47d93ebbb376bba97ff5d612717852a26fb8"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ifan112/demo-spring-webmvc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ifan112%2Fdemo-spring-webmvc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ifan112%2Fdemo-spring-webmvc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ifan112%2Fdemo-spring-webmvc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ifan112%2Fdemo-spring-webmvc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ifan112","download_url":"https://codeload.github.com/ifan112/demo-spring-webmvc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ifan112%2Fdemo-spring-webmvc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30567214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-16T04:42:47.996Z","status":"ssl_error","status_checked_at":"2026-03-16T04:42:44.668Z","response_time":96,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","spring","spring-webmvc"],"created_at":"2024-09-28T08:40:15.650Z","updated_at":"2026-03-16T05:11:27.140Z","avatar_url":"https://github.com/ifan112.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 引入spring-webmvc\n\nJava Servlet Web项目引入Spring WebMVC的方式有两种，第1中基于注解，第2中基于xml配置文件。\n\n1. 监听servlet容器，启动时创建spring容器，使用java注解的形式对spring容器进行配置，注册dispatcherServlet到servlet容器中。\n\n   ```java\n   @WebListener\n   public class DemoSpringWebMvcApplicationInitializer implements ServletContextListener {\n   \n       /**\n        * spring容器\n        */\n       private AnnotationConfigWebApplicationContext springContext;\n   \n       @Override\n       public void contextInitialized(ServletContextEvent sce) {\n           ServletContext servletContext = sce.getServletContext();\n   \n           // 初始化一个基于java注解的Web应用类型的spring容器\n           springContext = new AnnotationConfigWebApplicationContext();\n           // 向spring容器注册配置类，spring将解析该类上的注解，然后对容器进行配置\n           springContext.register(DemoSpringWebMvcApplicationConfiguration.class);\n   \n           // 注册dispatcherServlet到Servlet容器中。此后，该servlet将会接收和分发所有请求\n           ServletRegistration.Dynamic dispatcherServlet\n                   = servletContext.addServlet(\"dispatcherServlet\", new DispatcherServlet(springContext));\n           dispatcherServlet.setLoadOnStartup(1);\n           dispatcherServlet.addMapping(\"/\");\n       }\n   \n       @Override\n       public void contextDestroyed(ServletContextEvent sce) {\n           if (springContext != null) {\n               // 关闭spring容器\n               springContext.close();\n           }\n       }\n   }\n   ```\n\n   ```java\n   @Configuration\n   @EnableWebMvc\n   @ComponentScan(basePackages = \"com.ifan112.demo.swmvc\")\n   public class DemoSpringWebMvcApplicationConfiguration {\n   }\n   ```\n\n2. web.xml中注册dispatcherServlet，添加默认的spring配置文件/WEB-INF/dispatcherServlet-servlet.xml。\n\n   web.xml\n\n   ```xml\n   \u003c!DOCTYPE web-app PUBLIC\n           \"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN\"\n           \"http://java.sun.com/dtd/web-app_2_3.dtd\" \u003e\n   \n   \u003cweb-app\u003e\n       \u003cdisplay-name\u003eArchetype Created Web Application\u003c/display-name\u003e\n   \n       \u003cservlet\u003e\n           \u003cservlet-name\u003edispatcherServlet\u003c/servlet-name\u003e\n           \u003cservlet-class\u003eorg.springframework.web.servlet.DispatcherServlet\u003c/servlet-class\u003e\n           \u003cload-on-startup\u003e1\u003c/load-on-startup\u003e\n       \u003c/servlet\u003e\n   \n       \u003cservlet-mapping\u003e\n           \u003cservlet-name\u003edispatcherServlet\u003c/servlet-name\u003e\n           \u003curl-pattern\u003e/\u003c/url-pattern\u003e\n       \u003c/servlet-mapping\u003e\n   \u003c/web-app\u003e\n   ```\n\n   /WEB-INF/dispatcherServlet-servlet.xml\n\n   ```xml\n   \u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n          xmlns:context=\"http://www.springframework.org/schema/context\"\n          xmlns:mvc=\"http://www.springframework.org/schema/mvc\"\n          xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n               http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\n               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd\n               http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd\"\u003e\n   \n       \u003c!-- 配置spring扫描组件的路径。即让spring管理controller，service等组件类 --\u003e\n       \u003ccontext:component-scan base-package=\"com.ifan112.demo.swmvc\"/\u003e\n   \n       \u003c!-- 启用基于注解形式的webmvc功能。即让spring基于@RestController，@RequestMapping等注解分发、处理请求和响应 --\u003e\n       \u003cmvc:annotation-driven/\u003e\n   \n   \u003c/beans\u003e\n   ```\n\n\n\n# spring web容器启动入口\n\n不管是使用java注解配置还是xml配置文件的形式，spring web容器的启动过程都是一致的。将spring的DispatcherServlet注册到了servlet容器（tomcat）中，这就是启动spring web容器的入口。\n\n先看下DispatcherServlet的继承结构：\n\n```\nGenericServlet\n        .init()\t// servlet容器初始化时会调用该方法，子类可以实现自定义逻辑。例如，初始化spring容器。\n    |\n HttpServlet\t\t---- servlet规范\n    |\nHttpServletBean\t\t---- spring实现\n        .init()             // 重写了GenericServlet中的方法，调用initServletBean()方法\n        .initServletBean()  // 留给子类重写，实现自定义逻辑\n    |\nFrameworkServlet\n        .initServletBean()  // 重写了HtppServletBean中的方法，用于初始化spring容器\n    |\nDispatcherServlet\t---- 最主要的Servlet\n```\n\nservlet容器在初始化DispatcherServlet时，会调用继承自其父类GenericServlet的init()方法。spring DispatcherServlet的父类HttpServletBean重写了这个方法，并且留下了initServletBean()这个方法给子类用于实现自定义的逻辑。spring DispatcherServlet的父类FrameworkServlet重写了initServletBean()，并在该方法中初始化了spring容器。\n\n```java\n/**\n * servlet规范\n */\npublic abstract class GenericServlet\n    implements Servlet, ServletConfig, java.io.Seralizable { \n\n    public void init() throws ServletException {\n        // DispatcherServlet的父类HttpServletBean重写了这个方法\n    }\n}\n\n\npublic abstract class HttpServletBean extends HttpServlet implements .. {\n    /**\n     * spring DisptacherServlet的父类HttpServletBean重写了init()方法，\n     */\n    @Override\n    public final void init() throws ServletException {\n        // ... 其它逻辑\n        // 留给子类重写的方法\n        initServletBean();\n    }\n}\n\n\npublic abstract class FrameworkServlet extends HttpServletBean implements .. {\n    \n    /**\n     * spring DispatcherServlet的父类FrameworkServlet重写了initSevletBean()方法\n     */\n    @Override\n    protected final void initServletBean() throws ServletException {\n        // ... 其它逻辑\n        try {\n            // 初始化spring web容器\n            this.webApplicationContext = initWebApplicationContext();\n            initFrameworkServlet();\t// 又是留给子类重写的方法\n        } catch (Exception e) {\n            // ...\n        }\n    }\n}\n\n\npublic class DispatcherServlet extends FrameworkServlet {\n}\n```\n\n![启动入口截图](https://ws2.sinaimg.cn/large/006tKfTcgy1g0fcxmmx2gj30zh0u04ae.jpg)\n\nspring web容器启动入口调试截图\n\n\n\n# spring web容器启动过程分析","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifan112%2Fdemo-spring-webmvc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fifan112%2Fdemo-spring-webmvc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifan112%2Fdemo-spring-webmvc/lists"}