package com;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
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.Method;
import java.net.URL;
import java.util.*;
/**
*
*/
public class ZzpDispatchServlet extends HttpServlet {
private Properties contextConfig = new Properties();
private List<String> classNames = new ArrayList<>();
// IOC容器
private Map<String, Object> map = new HashMap<>();
private Map<String, Method> handlerMapping = new HashMap<>();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 执行调度
try {
doDispatch(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 执行调度
try {
doDispatch(req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
String url = req.getRequestURI();
String contextPath = req.getContextPath();
url = url.replaceAll(contextPath, "").replaceAll("/+", "/");
if (!this.handlerMapping.containsKey(url)) {
resp.getWriter().write("404 Not Found!");
return;
}
Map<String, String[]> params = req.getParameterMap();
Method method = this.handlerMapping.get(url);
String beanName = toLowerFirstCase(method.getDeclaringClass().getSimpleName());
method.invoke(map.get(beanName), params);
}
@Override
public void init(ServletConfig config) throws ServletException {
// 加载配置文件 web.xml获取
doLoadConfig("配置文件路径");
// 扫描包路径,提取相关的类
// 从配置文件加载(配置到配置文件)
doScanner("包路径");
// 初始化IOC容器,并且将扫描到的类实例化加入到IOC容器中
doInstance();
// 完成依赖注入
doAutowired();
// 初始化HandlerMapping,建立URL和Controller映射
doInitHandlerMapping();
System.out.println("spring init.");
}
private void doInitHandlerMapping() {
if (map.isEmpty()) {
return;
}
for (Map.Entry<String, Object> entry : map.entrySet()) {
Class<?> clazz = entry.getValue().getClass();
if (!clazz.isAnnotationPresent(Controller.class)) {
continue;
}
String baseUrl = "";
if(clazz.isAnnotationPresent(RequestMapping.class)){
RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
baseUrl = requestMapping.name();
}
for(Method method : clazz.getMethods()){
if(!method.isAnnotationPresent(RequestMapping.class)){
continue;
}
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
String url = ("/" + baseUrl + "/" + requestMapping.name()).replaceAll("/+", "/");
handlerMapping.put(url, method);
}
}
}
private void doAutowired() {
if (map.isEmpty()) {
return;
}
for (Map.Entry<String, Object> entry : map.entrySet()) {
Field[] fields = entry.getValue().getClass().getDeclaredFields();
for(Field field : fields){
if(!field.isAnnotationPresent(Autowired.class)){
continue;
}
Autowired autowired = field.getAnnotation(Autowired.class);
String beanName = autowired.annotationType().getName();
if("".equals(beanName)){
beanName = field.getType().getName();
}
field.setAccessible(true);
try {
// 用的反射
// 实现依赖注入
field.set(entry.getValue(), map.get(beanName));
} catch (IllegalAccessException e) {
e.printStackTrace();
continue;
}
}
}
}
private void doInstance() {
if (classNames.isEmpty()) {
return;
}
try {
for (String className : classNames) {
Class<?> clazz = Class.forName(className);
if (clazz.isAnnotationPresent(Controller.class)) {
// 默认类名首字母小写
String beanName = toLowerFirstCase(clazz.getSimpleName());
Object instance = clazz.newInstance();
map.put(beanName, instance);
} else if (clazz.isAnnotationPresent(Service.class)){
// 默认类名首字母小写
String beanName = toLowerFirstCase(clazz.getSimpleName());
// 自定义类名
Service service = clazz.getAnnotation(Service.class);
if (!"".equals(service.value())) {
beanName = service.value();
}
Object instance = clazz.newInstance();
map.put(beanName, instance);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String toLowerFirstCase(String name) {
char[] chars = name.toCharArray();
chars[0] += 32;
return String.valueOf(chars);
}
private void doScanner(String scanPackage) {
URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));
File classPath = new File(url.getFile());
for (File file : classPath.listFiles()) {
if (file.isDirectory()) {
doScanner(scanPackage + "/" + file.getName());
} else {
if (!file.getName().endsWith(".class")) {
continue;
}
String name = (scanPackage + "." + file.getName()).replace(".class", "");
classNames.add(name);
}
}
}
private void doLoadConfig(String path) {
InputStream is = this.getClass().getClassLoader().getResourceAsStream(path);
try {
contextConfig.load(is);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
欢迎大家提意见