Custom implementation of spring source code

Table of contents

1. This article achieves the goal

2. Custom annotations

3. Define the controller plus custom annotations

4. Recognize the annotation

5. Scan the directory and return all file names (fully qualified names) in the directory

6. Scan all classes and methods with these two annotations in the package where the file is located and put them in the map

7. Create an instance by reflection

8. Mobilize the instance through the exec method and execute the method in the instance

9. Execution result


1. This article achieves the goal

  •  custom annotation
  • recognize this annotation
  • Create an instance by reflection
  • Mobilize the instance through the exec method to execute the method in the instance

2. Custom annotations

For details, see: Custom Annotation (Annontation)_qq_52240237's Blog-CSDN Blog

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @ interface Controller {
}
import java.lang.annotation.*;

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

3. Define the controller plus custom annotations

@Controller 
@RequestMapping("test") 
public class TestController { 
    @RequestMapping 
    public String index(){ 
        System.out.println("This is the test class"); 
        return ""; 
    } 
    @RequestMapping("index1") 
    public String index1 (){ 
        System.out.println("This is the index1 method of the test class"); 
        return ""; 
    } 
}

4. Recognize the annotation

private static boolean isController(Class cl){

    Annotation annotation = cl.getAnnotation(Controller.class);
    if(annotation!=null){
        return  true;
    }
    return false;
}
private static boolean isRequestMapping(Class cl){
    Annotation annotation = cl.getAnnotation(RequestMapping.class);
    if(annotation!=null){
        return  true;
    }
    return false;
}
private  static boolean isRequestMapping(Method method){
    Annotation annotation = method.getAnnotation(RequestMapping.class);
    if(annotation!=null){
        return  true;
    }
    return false;
}
private static RequestMapping getRequestMapping(Class cl){
    Annotation annotation = cl.getAnnotation(RequestMapping.class);
    if(annotation instanceof  RequestMapping){
        return  (RequestMapping) annotation;
    }
    return null;
}
private static RequestMapping getRequestMapping(Method method){
    Annotation annotation = method.getAnnotation(RequestMapping.class);
    if(annotation instanceof  RequestMapping){
        return  (RequestMapping) annotation;
    }
    return null;
}

5. Scan the directory and return all file names (fully qualified names) in the directory

private static List<String> traverseFolder2(String path) {
    File file = new File(path);
    List<String> classFiles=new ArrayList<>();
    if (file.exists()) {
        LinkedList<File> list = new LinkedList<File>();
        File[] files = file.listFiles();
        for (File file2 : files) {
            if (file2.isDirectory()) {
                list.add(file2);
            } else {
                classFiles.add(file2.getAbsolutePath());
            }
        }
        File temp_file;
        while (!list.isEmpty()) {
            temp_file = list.removeFirst();
            //.listFiles():该目录中的文件和目录
            files = temp_file.listFiles(); 
            for (File file2 : files) { 
                //.isDirectory(): Check if the directory is a standard folder 
                if (file2.isDirectory()) { 
                    list.add(file2); 
                } else { 
                    //.getAbsolutePath(): returns the absolute pathname string of the abstract pathname 
                    classFiles.add(file2.getAbsolutePath()); 
                } 
            } 
        } } 
    else { 

    } 
    return classFiles; 
}

6. Scan all classes and methods with these two annotations in the package where the file is located and put them in the map

private static HashMap<String, Map<String,Method>> map=new HashMap<>();
private static HashMap<String, Object> objMap=new HashMap<>();
public static void scanner(String path,String packageName){
    List<String> paths = traverseFolder2(path);
    for (String p : paths) {
        p=p.substring(path.length()-1);
        try {
            String className=packageName+"."+p.replaceAll( Matcher.quoteReplacement(File.separator),".");
            String replace = className.replace(".class", "");
            Class<?> cl = ClassLoader.getSystemClassLoader().loadClass(replace);
            if(isController(cl)){
                if(isRequestMapping(cl)){
                    RequestMapping requestMapping = getRequestMapping(cl);
                    if(map.containsKey(requestMapping.value())){
                        throw  new RuntimeException("类多注解值:"+requestMapping.value());
                    }else {
                        map.put(requestMapping.value(),new HashMap<>());
                        objMap.put(requestMapping.value(),cl.newInstance());
                    }
                    Method[] declaredMethods = cl.getDeclaredMethods();
                    for (Method declaredMethod : declaredMethods) {
                        if(isRequestMapping(declaredMethod)){
                            RequestMapping mapping = getRequestMapping(declaredMethod);
                            if(map.get(requestMapping.value()).containsKey(mapping.value())){
                                throw  new RuntimeException("方法多注解值:"+requestMapping.value());
                            }else {
                                map.get(requestMapping.value()).put(mapping.value(),declaredMethod);
                            }
                        }
                    }
                }else {
                    throw  new RuntimeException("类无requestMapping");
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }


}

7. Create an instance by reflection

private static HashMap<String, Map<String,Method>> map=new HashMap<>();
private static HashMap<String, Object> objMap=new HashMap<>();
public static void exec(String classPath,String methodPath){
    if(objMap.get(classPath)==null){
        System.out.println("没有这个类 404");
    }else {
        if(map.get(classPath).get(methodPath)==null){
            System.out.println("没有这个方法 404");
        }else {
            try {
                map.get(classPath).get(methodPath).invoke(objMap.get(classPath));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}

8. Mobilize the instance through the exec method and execute the method in the instance

public class Main { 
    static { 
        //Find the fileName file under the same path as the current calling class 
        String path = Main.class.getResource("").getPath(); 
        //Return the package name of this class 
        String packageName = Main.class.getPackage().getName(); 
        HeaboyMvc.scanner(path,packageName); 
    } 

    public static void main(String[] args) { 
        HeaboyMvc.exec("",""); 
        HeaboyMvc.exec("test ","index1"); 
        HeaboyMvc.exec("test",""); 
        System.out.println("Hello World!"); 
    } 
}

9. Execution result

Guess you like

Origin blog.csdn.net/qq_52240237/article/details/132185075