SpringMVC学习

SpringMVC是 Spring提供的用于简化web开发的框架。

 

1.5 Servlet

Servlet能够响应请求的对象。接收请求,返回响应

SpringMVC可以认为是Servlet的封装。

 

1.6 SpringMVC开发流程回顾

各种配置。Controller,DispatchServlet,

1.9 url-pattern配置及原理剖析

静态资源配置

<mvc:default-servlet-handler/>

<resources location="classpath:/" mapping="resources/**">

1.10 数据处理机制Model、Map及ModelMap

用ModelMap传输局

1.11 请求参数绑定 (就是url上的参数)

http协议,超文本传输协议

1.12 简单类型参数

可以一致可以不一致,添加注解

1.13 绑定POJO及包装类型参数回顾

  • Pojo,属性名要对应
  • 形参名无所谓
  • 嵌套pojo  就是包装类型    

1.14 接受日期类型参数

  • 可以定义converter转换
  • 配在springmvc.xml 配置转换

1.15 深刻理解Rest风格

1)Rest风格请求是什么样的?

事例. rest是一个URL请求的风格,基于这种风格设计请求的Url。没有Rest的话,

http://localhost:8080/user/.action?id=3

 

有了rest风格之后,rest中认为互联网中的所有东西都是资源,就会有一个Uri标识。根据请求方式不同有不同的操作动作

用占位符表示参数

1.19 拦截器监听器

作用:

  • 做一些初始化工作
  • 监听web的特定事件,比如监听session
  • 拦截器:拦截handler

 

1.20 单个拦截器

四线接口 HandlerInterceptor

  • preHandle. 往往在这里完成权限校验, 默认不通过 false,需要修改值
  • postHandle
  • afterCompletion

2.1 手写MVC框架值原理回顾

 

 @Override
    public void init(ServletConfig config) throws ServletException {
        //加载配置文件
        String location = config.getInitParameter("contextConfigLocation");
        doLoadConfig(location);
        //扫描相关的类
        doScan("");
        //初始化相应Bean对象,实现IoC容器
        doInstance();
        //实现依赖注入
        doAutoWired();
        //构造一个handlerMapping处理器,映射器,将配置好的url和Method建立关系
        initHandlerMapping();

        System.out.println("Dispatcher init finish");
    }

2.4 doScan把设置需要扫描的路径下面的Controller类名存起

private void doScan(String packagePath) {
        String scanPackagePath = Thread.currentThread()
                .getContextClassLoader()
                .getResource("")
                .getPath()
                + packagePath.replaceAll("\\.", "/");

        File pack = new File(scanPackagePath);
        File[] files = pack.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                doScan(packagePath + "." + file.getName());
            } else if (file.getName().endsWith(".class")) {
                String className = packagePath+ "." + file.getName().replaceAll(".class", "");
                classNames.add(className);
            }
        }
    }

    //加载配置文件
    private void doLoadConfig(String location) {
        InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream(location);
        try {
            properties.load(resourceStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

2.5 initHandlerMapping, 把url和对应处理方法存起来

private void initHandlerMapping() {
        for (Map.Entry<String, Object> entry : ioc.entrySet()) {
            Class<?> clazz = entry.getValue().getClass();
            if (clazz.isAnnotationPresent(LagouController.class)) {
                String baseUrl = "";
                if (clazz.isAnnotationPresent(LagouRequestMapping.class)) {
                    LagouRequestMapping annotation = clazz.getAnnotation(LagouRequestMapping.class);
                    baseUrl = annotation.value();
                }

                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    if (method.isAnnotationPresent(LagouRequestMapping.class)) {
                        LagouRequestMapping methodAnnotation = method.getAnnotation(LagouRequestMapping.class);
                        String methodUrl = methodAnnotation.value();
                        String url = baseUrl + methodUrl;
                        handlerMapping.put(url, method);
                    }
                }
            }
        }
    }

 

  

2.6 doAutoWired, 把Autowired对应的实例存起

private void doAutoWired() {
        if (ioc.isEmpty()) {
            return;
        }

        //有对象再依赖注入处理
        for (Map.Entry<String, Object> entry : ioc.entrySet()) {
            Field[] declares = entry.getValue().getClass().getDeclaredFields();
            for (Field field : declares) {
                if (field.isAnnotationPresent(LagouAutoWired.class)) {
                    LagouAutoWired annotation = field.getAnnotation(LagouAutoWired.class);
                    String beanName = annotation.value();
                    if ("".equals(beanName.trim())) {
                        beanName = field.getType().getName();
                    }
                    field.setAccessible(true);
                    try {
                        field.set(entry.getValue(), ioc.get(beanName));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

 

2.7 实现ioc容器 (存controller,service,的实例,service有注解,找对应的interface,然后把interface对应上service实例)

private void doInstance() {
        if (classNames.isEmpty()) return;
        try {
            for (String className : classNames) {
                //DemoController
                Class<?> clazz = Class.forName(className);
                //区分controller 和 service
                if (clazz.isAnnotationPresent(LagouController.class)) {
                    //controller id不处理
                    String simpleName = clazz.getSimpleName();
                    String lowerName = lowerFirstAlpha(simpleName);
                    ioc.put(lowerName, clazz.newInstance());
                } else if (clazz.isAnnotationPresent(LagouService.class)) {
                    LagouService annotation = clazz.getAnnotation(LagouService.class);
                    //获取注解值
                    String beanName = annotation.value();
                    if (!"".equals(beanName.trim())) {
                        ioc.put(beanName, clazz.newInstance());
                    } else {
                        beanName = lowerFirstAlpha(clazz.getSimpleName());
                        ioc.put(beanName, clazz.newInstance());
                    }

                    // service 是有接口的, 放入ioc
                    Class<?>[] interfaces = clazz.getInterfaces();
                    for (Class<?> inter : interfaces) {
                        ioc.put(inter.getName(), clazz.newInstance());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

2.8 doScan 扫描包,存入class的路径

private void doScan(String packagePath) {
        String scanPackagePath = Thread.currentThread()
                .getContextClassLoader()
                .getResource("")
                .getPath()
                + packagePath.replaceAll("\\.", "/");

        File pack = new File(scanPackagePath);
        File[] files = pack.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                doScan(packagePath + "." + file.getName());
            } else if (file.getName().endsWith(".class")) {
                String className = packagePath + "." + file.getName().replaceAll(".class", "");
                classNames.add(className);
            }
        }
    }

 

2.9 doLoadConfig 把配置文件放入内存

private void doLoadConfig(String location) {
        InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream(location);
        try {
            properties.load(resourceStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

posted @ 2024-02-23 12:02  ylxn  阅读(2)  评论(0编辑  收藏  举报