Para entender la MVC Primavera correr el proceso, me di cuenta de puño y letra de Spring MVC

introducción

Código github: HTTPS: //github.com/erlieStar/servlet-learning
rama V3

El uso de un servlet 3.0 web.xml por lo que no tenemos, y toma notas

Nota definido

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
    String value() default "";
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
    String value() default "";
}

controlador central definida

Sustancialmente la totalidad de la lógica en esta clase, el siguiente proceso principal

  1. Creación de tiempo DispatcherServlet, tomcat llamará al método init (), asignación de dirección URL en el que la inicialización de procesamiento de método y correspondiente
  2. Cuando una solicitud para el método de llegar desde el uriInvokeInfoMap correspondiente, si existe un método correspondiente, el método de reflexión se llama para obtener el nombre de la página, la costura dirección de la página, se remitirá a la página correspondiente, de lo contrario 404
@WebServlet(urlPatterns="/", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {

    // 保存所有的handler
    private List<Object> beanList = new ArrayList<>();
    // 保存 uri 和 handler 的映射关系
    private Map<String, InvokeInfo> uriInvokeInfoMap = new HashMap<>();

    private static final String SLASH = "/";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = req.getRequestURI();
        String contextPath = req.getContextPath();
        // 去掉项目路径
        uri = uri.replace(contextPath, "");
        System.out.println(uri);
        if (uri == null) {
            return;
        }
        InvokeInfo invokeInfo = uriInvokeInfoMap.get(uri);
        if (invokeInfo == null) {
            resp.getWriter().write("404");
            return;
        }
        String pageName = (String)methodInvoke(invokeInfo.getBean(), invokeInfo.getMethod());
        viewResolver(pageName, req, resp);
    }

    // 视图解析器
    public void viewResolver(String pageName, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String prefix = "/";
        String suffix = ".jsp";
        req.getRequestDispatcher(prefix + pageName + suffix).forward(req, resp);
    }

    // 反射执行方法
    private Object methodInvoke(Object object, Method method) {
        try {
            return method.invoke(object);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void init() throws ServletException {
        // 获取指定包下的Class对象
        List<Class<?>> classList = ClassUtil.getAllClassByPackageName("com.javashitang.controller");
        // 找到所有标注了@Controller的类
        findAllConrollerClass(classList);
        // 初始化 uri 和 handler 的映射关系
        handlerMapping();
    }


    public void findAllConrollerClass(List<Class<?>> list) {
        list.forEach(bean -> {
            // 将被@Controller注解修饰的类放到beanList
            if (bean.isAnnotationPresent(Controller.class)) {
                try {
                    beanList.add(bean.newInstance());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    // 根据url找到相应的处理类
    public void handlerMapping() {
        for (Object bean : beanList) {
            Class<? extends Object> classInfo = bean.getClass();
            // 获取类上的@RequestMapping信息
            RequestMapping beanRequestMapping = classInfo.getDeclaredAnnotation(RequestMapping.class);
            String baseUrl = beanRequestMapping != null ? beanRequestMapping.value() : "";
            Method[] methods = classInfo.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
                // 获取方法上的@RequestMapping信息
                RequestMapping methodRequestMapping = method.getDeclaredAnnotation(RequestMapping.class);
                if (methodRequestMapping != null) {
                    String requestUrl = SLASH + baseUrl + SLASH + methodRequestMapping.value();
                    // 为了处理@Controller和@RequestMapping value 中加了 / 前缀的情况
                    requestUrl = requestUrl.replaceAll("/+", "/");
                    InvokeInfo invokeInfo = new InvokeInfo(bean, method);
                    uriInvokeInfoMap.put(requestUrl, invokeInfo);
                }
            }
        }
    }
}

El método y el correspondiente a una clase de bit no envasado

public class InvokeInfo {

    private Object bean;
    private Method method;

    public InvokeInfo(Object bean, Method method) {
        this.bean = bean;
        this.method = method;
    }
}

Para iniciar la prueba

@Controller
@RequestMapping("index")
public class IndexController {

    @RequestMapping("user")
    public String user() {
        return "user";
    }
}

Visitan las siguientes conexiones muestran correctamente

http://localhost:8080/show/index/user

atención de bienvenida

Aquí Insertar imagen Descripción

el blog de referencia

[1] https://my.oschina.net/liughDevelop/blog/1622646
[2] https://www.malaoshi.top/show_1EFutw6imbI.html

Publicados 385 artículos originales · ganado elogios 1471 · Vistas de 900.000 +

Supongo que te gusta

Origin blog.csdn.net/zzti_erlie/article/details/105020358
Recomendado
Clasificación