SpringMvc/src/main/java/com/tong/servlet/DispatcherServlet.java

217 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.tong.servlet;
import com.tong.annaotation.*;
import com.tong.controller.TongController;
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 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;
public class DispatcherServlet extends HttpServlet {
List<String> classNames = new ArrayList<String>();
Map<String, Object> beans = new HashMap<String, Object>();
Map<String, Object> handlerMap = new HashMap<String, Object>();
// private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
//把所有的bean扫描 ----扫描所有的class文件
scanPackage("com.tong");
doInstance(); //根据全类名创建bean
doIoc(); //根据bean进行依赖注入
buildUrlMapping(); //建立映射关系
}
private void scanPackage(String basePackage) {
URL url = this.getClass().getClassLoader().getResource("/"+basePackage.replaceAll("\\.", "/"));
String fileStr = url.getFile();
File file = new File(fileStr);
String[] filesStr = file.list();
for (String path : filesStr) {
File filePath = new File(fileStr+path);
if (filePath.isDirectory()) {
scanPackage(basePackage+"."+path);
}else {
//加入list
classNames.add(basePackage+"."+filePath.getName());
}
}
}
//根据扫描的list全类名进行实例化
private void doInstance() {
if (classNames.size() <= 0) {
System.out.println("包扫描失败.....");
return;
}
//遍历list的所有Class类
for (String className : classNames) {
String cn = className.replace(".class", "");
try {
Class<?> clazz = Class.forName(cn);
if (clazz.isAnnotationPresent(EnjoyController.class)) {
Object instance = clazz.newInstance();//创建控制类
EnjoyRequestMapping requestMapping = clazz.getAnnotation(EnjoyRequestMapping.class);
String rmvalue = requestMapping.value();
beans.put(rmvalue, instance);
}else if (clazz.isAnnotationPresent(EnjoyService.class)) {
EnjoyService service = clazz.getAnnotation(EnjoyService.class);
Object instance = clazz.newInstance();
beans.put(service.value(), instance);
}else {
continue;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
//把service注入到controller
public void doIoc() {
if (beans.entrySet().size() <= 0) {
System.out.println("没有一个实例化类");
}
//把map里所有的实例化遍历出来
for (Map.Entry<String, Object> entry: beans.entrySet()) {
Object instance = entry.getValue();
Class<?> clazz = instance.getClass();
if (clazz.isAnnotationPresent(EnjoyController.class)) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(EnjoyAutowired.class)) {
EnjoyAutowired auto = field.getAnnotation(EnjoyAutowired.class);
String key = auto.value();
field.setAccessible(true);
try {
field.set(instance, beans.get(key));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}else {
continue;
}
}
}else {
continue;
}
}
}
private void buildUrlMapping() {
if (beans.entrySet().size() <= 0) {
System.out.println("没有实例化____");
return;
}
for (Map.Entry<String, Object> entry: beans.entrySet()) {
Object instance = entry.getValue();
Class<?> clazz = instance.getClass();
if (clazz.isAnnotationPresent(EnjoyController.class)) {
EnjoyRequestMapping requestMapping = clazz.getAnnotation(EnjoyRequestMapping.class);
String classPath = requestMapping.value();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(EnjoyRequestMapping.class)) {
EnjoyRequestMapping methodMapping = method.getAnnotation(EnjoyRequestMapping.class);
String methodPath = methodMapping.value();
handlerMap.put(classPath+methodPath, method);
}else {
continue;
}
}
}else {
continue;
}
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求路径
String uri = req.getRequestURI();
String context = req.getContextPath();
String path = uri.replace(context, "");
Method method = (Method) handlerMap.get(path);
TongController instance = (TongController) beans.get("/"+path.split("/")[1]);
Object[] args = hand(req, resp, method);
try {
method.invoke(instance, args);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private static Object[] hand(HttpServletRequest request, HttpServletResponse response, Method method) {
//拿到待执行的方法有哪些参数
Class<?>[] paramClazzs = method.getParameterTypes();
//根据参数的个数new 一个参数的数组将方法的所有参数赋值到args
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 (EnjoyRequestParam.class.isAssignableFrom(paramAn.getClass())) {
EnjoyRequestParam rp = (EnjoyRequestParam) paramAn;
args[args_i++] = request.getParameter(rp.value());
}
}
}
index++;
}
return args;
}
}