【仿写框架之仿写Tomact】二、初始化阶段加载项目中所有servlet类对象

文章目录

  • 1、自定义@MyWebServlet 注解
  • 2、创建HttpServlet文件
  • 3、加载项目中的所有以.java结尾的文件
  • 4、收集项目中带有@MyWebServlet 的类对象

【仿写框架之仿写Tomact】二、初始化阶段加载项目中所有servlet类对象_第1张图片

1、自定义@MyWebServlet 注解

我们知道,tomcat是依据@WebServlet注解去收集所有servlet类的。

import java.lang.annotation.*;

//该注解可以应用于类、接口(包括注解类型)、枚举
@Target(ElementType.TYPE)//ElementType.TYPE
//该注解标记的元素可以被Javadoc 或类似的工具文档化
@Documented
//该注解的生命周期,由JVM 加载,包含在类文件中,在运行时可以被获取到
@Retention(RetentionPolicy.RUNTIME)//RUNTIME

/**
 * @description:
 * @author: YHZ
 * @date: 2023/8/15 14:36
 **/
public @interface MyWebServlet {
    String urlMapping()default "";
}

2、创建HttpServlet文件

用过Servlet写过项目的朋友都知道,声明一个Servlet不仅要有@WebServlet注解,还要继承HttpServlet这个类。

public abstract class HttpServlet {

    //实现doGet方法
    public abstract void doGet(HttpRequest request, HttpResponse response);

    //实现doPOST方法
    public abstract void doPost(HttpRequest request, HttpResponse response);

    //实现service方法进行判断
    public void service(HttpRequest request, HttpResponse response){
        if ("GET".equals(request.getMethod())){
            doGet(request,response);
        }else if("POST".equals(request.getMethod())){
            doPost(request,response);
        }
    }
}

3、加载项目中的所有以.java结尾的文件

public class FileChooseConfig {

    //存的是该项目文件夹中所有.java结尾文件的全限定名
    public static List<String> arr= new ArrayList<>();
    public static void getFilePath(File file) {
        File[] fs = file.listFiles();
        for (File f : fs) {
            if (f.isDirectory()){
                getFilePath(f);
            }
            if (f.isFile()) {
                String filepath = f.toString();
                filepath = filepath.split("main")[1];
                filepath = filepath.substring(6,filepath.length());
                if( filepath.endsWith(".java")) {
                    //把是.java文件的全类名放到arr中
                    arr.add(filepath.replace("\\", ".").replace(".java", ""));
                }
            }
        }
    }
}

4、收集项目中带有@MyWebServlet 的类对象

public class FileChooseConfig {
    //key为urlMapping路径,value为通过全类名反射得到的servlet类对象
    public static Map<String,Class> webServletMap = new ConcurrentHashMap<>();


    //查找所有controller,并创建对象装入Map里(“url”:Object)
    public static void chooseWebServlet() {
        for(String file: arr){
            try {
                Class<?> aClass = Class.forName(file);
                //如果有WebServlet注解
                if(aClass.isAnnotationPresent(MyWebServlet.class)) {

                    MyWebServlet webServlet = getUrlMapping(aClass);
                    //如果之前已经有了一样的  不同controller的requestmapping的值,说明有冲突。
                    if (webServletMap.containsKey(webServlet.urlMapping())) {
                        throw new RuntimeException("类多注解值:" + webServlet.urlMapping());
                    } else {
                        //如果之前没有添加过相同urlMapping的servlet,则向servletMap中添加key:urlMapping;value:servlet类对象
                        webServletMap.put(webServlet.urlMapping(),  aClass);
                    }
                }
            }catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }


    public static MyWebServlet getUrlMapping(Class cl){
        Annotation annotation = cl.getAnnotation(MyWebServlet.class);
        if(annotation instanceof  MyWebServlet){
            return  (MyWebServlet) annotation;
        }
        return null;
    }

}

你可能感兴趣的:(servlet,tomcat,java)