# 项目搭建

作者:Ethan.Yang
博客:https://blog.ethanyang.cn (opens new window)
相关源码参考: 手写Spring代码仓库 (opens new window)


本系列文章将通过手写简化版SpringMVC IOC DI AOP等功能, 分析Spring源码, 以web项目为例, 默认读者已知并熟练使用Spring

# 一、Spring 容器初始化对比

# 传统 Spring MVC

  • 初始化起点DispatcherServlet.init()

  • 流程

    1. Servlet 容器(如 Tomcat)启动,根据 web.xmlServletContainerInitializer 加载 DispatcherServlet
    2. 调用 DispatcherServlet.init()initServletBean()
    3. initServletBean() 中创建 Spring IoC 容器WebApplicationContext
    4. 调用 onRefresh() 刷新容器
    5. 调用 initStrategies() 初始化 Spring MVC 各种策略(HandlerMapping、ViewResolver 等)
  • 初始化链路大致为:

    HttpServlet → HttpServletBean → FrameworkServlet → DispatcherServlet
                                        ↑
                              initServletBean():创建 IOC 容器
                                                ↓
                                    onRefresh()initStrategies()
    
    1
    2
    3
    4
    5

# SpringBoot 中

  • 初始化起点SpringApplication.run()

  • 流程

    1. 调用 SpringApplication.run() → 创建并刷新 ApplicationContext(通常是 AnnotationConfigServletWebServerApplicationContext
    2. Spring 容器启动过程中,初始化 嵌入式 Servlet 容器(Tomcat/Jetty/Undertow)
    3. 容器启动完成后,注册并初始化 DispatcherServlet


# 二、手写Spring思路

本篇为张基于spring实现手写, 具体思路看下图

从图来看, 将手写spring分为如下几步

  1. serverlet.init()方法中需要初始化容器
  2. 读取配置文件
  3. 扫描相关类
  4. 初始化容器, 实例化bean IOC
  5. 完成DI
  6. AOP
  7. MVC

其中 2 3 4 5 6是属于容器的功能, 1 和 7是属于serverlet自身的功能

平时使用applicationContext.getBean() 也就是DI的入口, applicationContext应该在serverlet.init()方法中被初始化


# 三、项目搭建准备

# 配置 application.properties

scanPackage=com.yym.demo
1

指定要扫描的包路径。

# 配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
		 xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
		 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
		 version="2.4">
	<display-name>Yym Web Application</display-name>
	<servlet>
		<servlet-name>yymmvc</servlet-name>
		<servlet-class>com.yym.spring.framework.webmvc.servlet.YymDispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:application.properties</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>yymmvc</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

定义核心分发 Servlet,并指定初始化配置文件, 至此项目搭建完毕