web.xml中声明此dispatcherServlet, 目的: ①表示这是个会被tomcat容器识别的servlet, ②拦截所有请求
<?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/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringSim2</display-name>
<servlet>
<servlet-name>springsim2</servlet-name>
<servlet-class>com.spring.sim.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springsim2</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app> src下创建application.properties, 指定需要被扫描的包
path=com.spring.sim
web.xml中将properties文件设置为启动时被load
⚠ 此步骤为可选, 在DispatcherServlet中声明也可以
此步完成后, 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/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringSimv1</display-name>
<servlet>
<servlet-name>springsim</servlet-name>
<servlet-class>pro.yizheng.DispatcherServlet</servlet-class>
<!-- 指定配置文件 -->
<init-param>
<param-name>webXmlInitParam-properties</param-name>
<param-value>application.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springsim</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app> 声明要用到的Annotation
Annotation source code:
@Documented
@Retention(RUNTIME)
@Target(FIELD)
public @interface SSAutowired {
String value() default "";
}
@Documented
@Retention(RUNTIME)
@Target({ TYPE})
public @interface SSController {
String value() default "";
}
@Documented
@Retention(RUNTIME)
@Target({TYPE,METHOD})
public @interface SSRequestMapping {
String value() default "";
}
@Documented
@Retention(RUNTIME)
@Target(PARAMETER)
public @interface SSRequestParam {
String value() default "";
}
@Documented
@Retention(RUNTIME)
@Target(TYPE)
public @interface SSService {
String value() default "";
} 编写service类, 目的: 模拟spring组件的功能
@SSService
public class Service {
public void get(String name) {
System.out.println(name);
}
} 编写Action, 目的: 模拟Springmvc的action, 实际上模拟的Action已经和SpringMVC的相同了
@SSController
@SSRequestMapping("/demo")
public class DemoAction {
@SSAutowired
private SSDemoService service;
@SSRequestMapping("/query")
public void query(HttpServletRequest requeust, HttpServletResponse response, @SSRequestParam("name") String name) {
String reString = service.get(name);
try {
response.getWriter().write(reString);
} catch (Exception e) {
e.printStackTrace();
}
}
@SSRequestMapping("/add")
public void add(HttpServletRequest requeust, HttpServletResponse response, @SSRequestParam("name") String name) {
try {
response.getWriter().write("this is add");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} DispatcherServlet是整个工程的大脑, 它负责整个容器的的初始化, 资源读取管理和请求分发.
此工程中, dispatcherServlet分为以下几个部分:
初始化容器
接收并处理请求
看起来似乎很简单, 但实现起来还是有一些麻烦的.
下面我们开始.
编写初始化方法 - 此方法名无法更改, 只能是init方法, 这是Servlet规范
而在init方法中, 第一步需要提取出所有的Java类型文件, 每一个文件都要对应一个或多个路径, 所以我们
private Map<String, Object> javaFiles = new HashMap<>();
private void scanJavaFiles(String path) {
// 通过application.properties中设定的包名, 找到其下所有的java class文件
File pathDir = new File(this.getClass().getResource(path).getPath());
String[] pathList = pathDir.list();
for (String temFile : pathList) {
File tempFile = new File(pathDir+ "/" + temFile);
// 如果是目录的话, 即递归操作
if (tempFile.isDirectory()) {
scanJavaFiles(path + "/" + temFile);
}
// 非目录, 得到子节点
if (temFile.endsWith(".class")) {
javaFiles.put(path+ "/" + temFile.replace(".class", ""), null);
}
}
}