手写MVC框架

Posted 怀瑾Hello World

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写MVC框架相关的知识,希望对你有一定的参考价值。

手写MVC

1.SpringMvc执行大致原理

tomcat加载web.xml,前端控制器DispatchServlet加载指定配置文件springmvc.xml 包扫描,扫描注解Controller,Service,RequestMapping,Autowire Ioc容器就是要进行相应Bean初始化以及依赖维护关系 SpringMvc相关组件初始化,建立url和method之间的映射关系 等待请求进来,处理请求....

2.手写Mvc之注解开发

2.0.配置文件

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>mvc</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>mvc Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!--servlet-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <!--commoms-lang-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.12.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!--编译插件,防止jdk在编译时将参数识别为args1,而不使用自己原本的参数名称-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <encoding>utf-8</encoding>
          <compilerArgs>
            <arg>-parameters</arg>
          </compilerArgs>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <configuration>
          <port>8080</port>
          <path>/</path>
        </configuration>
        <version>2.2</version>
      </plugin>
    </plugins>
  </build>


</project>

  • web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <servlet>
    <servlet-name>MvcDispatcherServlet</servlet-name>
    <servlet-class>com.edu.mvcframework.servlet.MvcDispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>mvc.properties</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>MvcDispatcherServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>
  • mvc.properties
scanPackage=com.demo

2.1.自定义注解类

  • MvcController
package com.edu.mvcframework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcController 
    String value() default "";


  • MvcService
package com.edu.mvcframework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcService 
    String value() default "";


  • MvcRequestMapping
package com.edu.mvcframework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE,ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcRequestMapping 
    String value() default "";


  • MvcAutowire
package com.edu.mvcframework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MvcAutowire 
    String value() default "";


  • Security
package com.edu.mvcframework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE,ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Security 

    String[] value();


2.2.自定义前端控制器

  • MvcDispatcherServlet
package com.edu.mvcframework.servlet;

import com.edu.mvcframework.annotation.*;
import com.edu.mvcframework.pojo.Handle;
import org.apache.commons.lang3.StringUtils;

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.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.regex.Pattern;

public class MvcDispatcherServlet extends HttpServlet 

    private Properties properties = new Properties();

    // 定义一个容器,存储扫描到的所有类的全路径名称
    private Set<String> classNames = new HashSet<>();

    // ioc容器
    private Map<String,Object> iocMap = new HashMap<>();

    // 存储url和method的映射关系容器
    private Map<String, Handle> handlerMap = new HashMap<>();

    // 标识已处理过的类
    private Set<String> handledClasses = new HashSet<>();

    @Override
    public void init(ServletConfig config) throws ServletException 
        String mvcPropFile = config.getInitParameter("contextConfigLocation");
       try 
           // 1.加载自定义mvc框架配置文件
           doLoadProperties(mvcPropFile);

           // 2.扫描包,获取所有类
           doScan(properties.getProperty("scanPackage"));

           // 3.实例化对象,将含有自定义注解的类存储到ioc容器当中
           doInstance();

           // 4.处理类之间的依赖关系
           doAutowire();

           // 5.处理url和method之间的映射关系,进行存储
           doInitHandleMapping();

           // 等待请求到来
       catch (Exception e)
           e.printStackTrace();
       
    

    private void doInitHandleMapping() throws ClassNotFoundException 
        if(iocMap.size() == 0)return;
        for (Map.Entry<String, Object> entry : iocMap.entrySet()) 

            Class<?> aClass = entry.getValue().getClass();
            // 已经处理过映射的不在处理
            if (handledClasses.contains(aClass.getName()))continue;

            // 非controller类,不进行处理
            if (!aClass.isAnnotationPresent(MvcController.class)以上是关于手写MVC框架的主要内容,如果未能解决你的问题,请参考以下文章

手写MVC框架

手写MVC框架

手写MVC框架

手写一个迷你版Spring MVC框架

手写Spring MVC框架,像高手路线出发!

从 0 开始手写一个 Spring MVC 框架,向高手进阶!