模似手写spring

package com.mySpring.it.servlet;


import com.sun.xml.internal.ws.util.StringUtils;

import javax.print.DocFlavor;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.plaf.basic.BasicSeparatorUI;
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;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DisptacherServlet extends HttpServlet {

    private static final String LOCATION = "contextConfigLocation";

    private Properties properties = new Properties();

    private List<String> className = new ArrayList<>();

    private Map<String, Object> ioc = new ConcurrentHashMap<>();

    private Map<String, Method> handlerMapping = new ConcurrentHashMap();

    public DisptacherServlet() {
        super();
    }

    @Override
    public void init(ServletConfig config) throws ServletException {

        doLoadConfig(config);

        doScanner(properties.getProperty("scanPackage"));

        doInstance();

        doAutowired();

        initHandlerMapping();

        System.out.println("gupaoedu mvcframework is init...");
    }

    private void doLoadConfig(ServletConfig config) {
        InputStream is = null;
        try {
            is = this.getClass().getClassLoader().getResourceAsStream(LOCATION);
            properties.load(is);
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            if (null == is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void doScanner(String scanPackage) {
        URL url = this.getClass().getClassLoader().getResource(scanPackage.replaceAll("\\.", "/"));
        File file = new File(url.getFile());
        for (File listFile : file.listFiles()) {
            if (listFile.isDirectory()) {
                doScanner(scanPackage + "." + listFile.getName());
            } else {
                className.add(scanPackage + "." + listFile.getName().replace(".class", "").trim());
            }
        }
    }

    private void doInstance() {
        if (className.isEmpty()) {
            return;
        }
        try {
            for (String fileName : className) {
                Class<?> instance = Class.forName(fileName);
                if (instance.isAnnotationPresent(Controller.class)) {
                    char[] chars = instance.getSimpleName().toCharArray();
                    chars[0] += 32;
                    String beanName = new String(chars);
                    ioc.put(beanName, instance);
                }
                if (instance.isAnnotationPresent(Service.class)) {
                    String value = instance.getDeclaredAnnotation(Service.class).value();
                    if (!"".equals(value.trim())) {
                        ioc.put(value, instance);
                        continue;
                    }
                    //如果自已没设,就按接口类创建一个实例
                    Class<?>[] interfaces = instance.getInterfaces();
                    for (Class<?> anInterface : interfaces) {
                        ioc.put(anInterface.getName(), instance.newInstance());
                    }
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            System.out.println(e);
        }
    }

    private void doAutowired() {
        if (ioc.isEmpty()) {
            return;
        }
        for (Map.Entry<String, Object> entry : ioc.entrySet()) {
            Field[] fields = entry.getValue().getClass().getFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    String autowiredBeanName = field.getDeclaredAnnotation(Autowired.class).value();
                    if ("".equals(autowiredBeanName.trim())) {
                        autowiredBeanName = field.getType().getName();
                    }
                    field.setAccessible(true);
                    try {
                        field.set(entry.getValue(), ioc.get(autowiredBeanName));
                    } catch (IllegalAccessException e) {
                        System.out.println(e);
                    }
                }
            }
        }
    }

    private void initHandlerMapping() {
        if (ioc.isEmpty()) {
            return;
        }
        for (Map.Entry<String, Object> entry : ioc.entrySet()) {
            Class<?> clazz = entry.getValue().getClass();
            if (!clazz.isAnnotationPresent(Controller.class)) {
                continue;
            }
            String baseUri = "";
            if (clazz.isAnnotationPresent(RequestMapping.class)) {
                baseUri = clazz.getDeclaredAnnotation(RequestMapping.class).value();
            }

            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(RequestMapping.class)) {
                    String methodUri = method.getDeclaredAnnotation(RequestMapping.class).value();
                    String uri = ("/" + baseUri + "/" + methodUri).replaceAll("/+", "/");
                    handlerMapping.put(uri, method);
                    System.out.println("mapper " + uri + "," + method);
                }
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            doDispatch(req, resp);
        } catch (Exception e) {
            resp.getWriter().write("500 Execption, Details rn" + Arrays.toString(e.getStackTrace())
                    .replaceAll("\\[|\\]", "\\").replaceAll("\\s", "\r\n"));
        }
    }

    private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        if (handlerMapping.isEmpty()) {
            return;
        }
        String uri = req.getRequestURI();
        String contextPath = req.getContextPath();
        uri = uri.replaceAll(contextPath, "").replaceAll("/+", "/");

        if (!handlerMapping.containsKey(uri)) {
            resp.getWriter().write("404 Not Found!");
            return;
        }

        Map<String, String[]> parameterMap = req.getParameterMap();
        Method method = handlerMapping.get(uri);
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object[] paramValue = new Object[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> parameterType = parameterTypes[i];
            if (parameterType == HttpServletRequest.class) {
                paramValue[i] = req;
                continue;
            }
            if (parameterType == HttpServletResponse.class) {
                paramValue[i] = resp;
                continue;
            }
            if (parameterType == String.class) {
                for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                    String value = Arrays.toString(entry.getValue());
                    value = value.replaceAll("\\[|\\]", "").replaceAll(",\\s", ",");
                    paramValue[i] = value;
                }
            }
        }

        //
        try {
            String simpleName = method.getDeclaringClass().getSimpleName();
            char[] chars = simpleName.toCharArray();
            chars[0] += 32;
            String beanName = String.valueOf(chars);
            method.invoke(ioc.get(beanName), paramValue);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

版权声明:本文为wenwentana原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。