1.springmvc本质上是对servlet的封装,当用户发送一个请求后,其springmvc的工作原理如图所示:
其流程为:
1、 用户发送请求至前端控制器DispatcherServlet。
2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、 DispatcherServlet调用HandlerAdapter处理器适配器。
5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、 Controller执行完成返回ModelAndView。
7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、 ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、 DispatcherServlet响应用户。
2.接下来就根据流程来编写一个简单的springmvc的demo案例:
package com.xyf.mvc.servlet;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.xyf.mvc.annotation.Autowired;
import com.xyf.mvc.annotation.RequestMapping;
import com.xyf.mvc.annotation.RequestParam;
import com.xyf.mvc.annotation.Service;
import com.xyf.mvc.annotation.xyfController;
import com.xyf.mvc.controller.testController;
/**
* Servlet implementation class dispatcherServlet
*/
public class dispatcherServlet extends HttpServlet {
List<String> classNames = new ArrayList<String>();
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Object> handerMap = new HashMap<String, Object>();
private String scan_packageName="";
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public dispatcherServlet() {
super();
// TODO Auto-generated constructor stub
}
public void init(ServletConfig config) {
doScanXml();
doScan(scan_packageName);// 扫描这个包下面的所有类
doInstance();// 创建实例并保存
doAutowired();// 射入
doMapping();// 根据映射找到方法 --> 找到method
}
private void doScanXml() {
//通过xml文件获得需要扫描的包名
URL url=this.getClass().getClassLoader().getResource("config.xml");
File file =new File(url.getFile());
SAXReader reader=new SAXReader();
Document document = null;
try {
document = reader.read(file);
} catch (DocumentException e) {
e.printStackTrace();
}
Element root=document.getRootElement();
List<?> list=root.elements();
for(Object object:list)
{
Element element = (Element)object;
scan_packageName=element.getText();
}
}
private void doScan(String basePackage) {
URL url = this.getClass().getClassLoader().getResource(("/" + basePackage.replaceAll("\\.", "/")));// 转换为文件类型
String str = url.getFile();
File file = new File(str);
String[] fileStr = file.list(); // 拿到当前包下面的所有 .class文件
for (String path : fileStr) {
File filePath = new File(str + path); //
if (filePath.isDirectory()) {
doScan(basePackage + "." + path);
} else // java类
{
classNames.add(basePackage + "." + filePath.getName());
}
}
}
private void doInstance() {
for (String className : classNames) {
// 去掉class后缀名
String cn = className.replace(".class", "");
try {
Class<?> clazz = Class.forName(cn);
if (clazz.isAnnotationPresent(xyfController.class)) {
Object instace = clazz.newInstance();
// map.put instace
RequestMapping reqMap = clazz.getAnnotation(RequestMapping.class);
String key = reqMap.value();
map.put(key, instace); // 放入map
} else if (clazz.isAnnotationPresent(Service.class)) {
Object instace = clazz.newInstance();
// map.put instace
Service reqMap = clazz.getAnnotation(Service.class); // 拿到service作为一个key
String key = reqMap.value();
map.put(key, instace); // 放入map
} else {
continue;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
private void doAutowired() {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object instance = entry.getValue();// 拿到对象
Class<?> clazz = instance.getClass();
if (clazz.isAnnotationPresent(xyfController.class)) {
Field[] fields = clazz.getDeclaredFields();
for (Field fd : fields) {
if (fd.isAnnotationPresent(Autowired.class)) {
// 如果有autowired 则注入
Autowired auto = fd.getAnnotation(Autowired.class);
String key = auto.value();
Object value = map.get(key);
fd.setAccessible(true);// 打开私处
try {
fd.set(instance, value);// 射入
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
private void doMapping() {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object instance = entry.getValue();// 拿到对象
Class<?> clazz = instance.getClass();
if (clazz.isAnnotationPresent(xyfController.class)) {
RequestMapping reqMapping = clazz.getAnnotation(RequestMapping.class);
String classPath = reqMapping.value(); //
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
if (method.isAnnotationPresent(RequestMapping.class)) {
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
String methodPath = requestMapping.value();
handerMap.put(classPath + methodPath, method);
} else {
continue;
}
}
}
}
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求路径
String uri = request.getRequestURI(); // projectName
String context = request.getContextPath();
String path = uri.replace(context, ""); // key
Method method = (Method) handerMap.get(path); // method --
if (!path.equals("/")&&method!=null) {
testController instance = (testController) map.get("/" + path.split("/")[1]);
Object args[] = han(request, response, method);
try {
method.invoke(instance, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
private Object[] han(HttpServletRequest request, HttpServletResponse response, Method method) {
Class<?>[] paramClazzs = method.getParameterTypes();
Object[] args = new Object[paramClazzs.length];
int args_i = 0;
int index = 0;
for (Class<?> paramClazz : paramClazzs) {
if (ServletRequest.class.isAssignableFrom(paramClazz)) {
args[args_i++] = request;
}
if (ServletResponse.class.isAssignableFrom(paramClazz)) {
args[args_i++] = response;
}
Annotation[] paramAns = method.getParameterAnnotations()[index];
if (paramAns.length > 0) {
for (Annotation paramAn : paramAns) {
if (RequestParam.class.isAssignableFrom(paramAn.getClass())) {
RequestParam rp = (RequestParam) paramAn;
args[args_i++] = request.getParameter(rp.value());
}
}
}
index++;
}
return args;
}
}
© 2019 GitHub, Inc.
全套代码地址:https://github.com/RAOE/Iframe