手写 Spring MVC
不多说,简历装 X 必备。不过练好还是需要求一定的思维能力。
一、整体思路
思路要熟练背下来
1)配置阶段
- 配置 web.xml:
- <sevlet>
- XDispatchServlet
- 设定 init-param: contextConfigLocation = applicationContext.properties
- <servlet-mapping>
- 设定 url-pattern: /*
- 配置 Annotation: @XController @XService @XAutowired @XRequestMapping
2)初始化阶段
- IOC:
- 调用 init() 方法: 加载配置文件
- IOC 容器初始化: Map<String, Object>
- 扫描相关的类: scan-package=“com.xiaopengwei”
- 创建实例化并保存到容器: 同过反射机制将类实例化放入 IOC 容器中
- DI:
- 进行 DI 操作: 扫描 IOC 容器中的实例,给没有赋值的属性自动赋值
- MVC:
- 初始化 HandlerMapping: 将一个 URL 和一个 Method 进行一对一的关联映射 Map<String, Method>
3)运行阶段
- 调用 doGet() / doPost() 方法: Web 容器调用 doGet() / doPost() 方法,获得 request/response 对象
- 匹配 HandleMapping: 从 request 对象中获得用户输入的 url,找到其对应的 Method
- 反射调用 method.invoker(): 利用反射调用方法并返回结果
- response.getWrite().write(): 将返回结果输出到浏览器,手写 Spring MVC
二、源代码
项目结构:
源代码:
(1)在 pom.xml 引入一个 jar 包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
(2)web.xml 文件:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>xmvc</servlet-name>
<servlet-class>com.xiaopengwei.xspring.servlet.XDispatchServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--you can't use classpath*: -->
<param-value>application.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>xmvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
(3)application.properties 文件:
scan-package=com.xiaopengwei
(4)自定义注解 XAutowired:
package com.xiaopengwei.xspring.annotation;
import java.lang.annotation.*;
/**
* <p>
*
* @author http://www.wityx.com
*
*/
@Target({
ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XAutowired {
String value() default "";
}
(5)自定义注解 XController:
package com.xiaopengwei.xspring.annotation;
import java.lang.annotation.*;
/**
* <p>
*
* @author http://www.wityx.com
*
*/
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XController {
String value() default "";
}
(6)自定义注解 XRequestMapping:
package com.xiaopengwei.xspring.annotation;
import java.lang.annotation.*;
/**
* <p>
*
* @author http://www.wityx.com
*
*/
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XRequestMapping {
String value() default "";
}
(7)自定义注解 XService:
package com.xiaopengwei.xspring.annotation;
import java.lang.annotation.*;
/**
* <p>
*
* @author http://www.wityx.com
*
*/
@Target({
ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XService {
String value() default "";
}
(8)核心 XDispatchServlet:
package com.xiaopengwei.xspring.servlet;
import com.xiaopengwei.xspring.annotation.XAutowired;
import com.xiaopengwei.xspring.annotation.XController;
import com.xiaopengwei.xspring.annotation.XRequestMapping;
import com.xiaopengwei.xspring.annotation.XService;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL