1. ControllerDefinition
package com.csdn.mymvc.core; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; //Suppose there is a uri:/fruit/index @Data @NoArgsConstructor @AllArgsConstructor public class ControllerDefinition { private String requestMapping; private Object controllerBean; private Map<String, Method> methodMappingMap = new HashMap<>(); }2. ComponentScan
package com.csdn.mymvc.core; import com.csdn.mymvc.annotation.*; import java.io.File; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.*; public class ComponentScan { public static Map<String, Object> beanFactory = new HashMap<>(); public static Map<String, ControllerDefinition> controllerBeanMap = new HashMap<>(); static String path = null; static { //Analyze folder path = ComponentScan.class.getClassLoader().getResource("").getPath(); // /F:/IdeaProjects/workspace/review/pro13-fruit-DispatcherServlet/target/ // pro13-fruit-DispatcherServlet-1.0-SNAPSHOT/WEB-INF/classes/ //The root directory of the computer's hard disk is /, no matter what operating system it is. It's just Microsoft's artificial concept of dividing drive letters. //System.out.println(path); path = path.substring(1); //System.out.println(path); // F:/IdeaProjects/workspace/review/pro13-fruit-DispatcherServlet/target // /pro13-fruit-DispatcherServlet-1.0-SNAPSHOT/WEB-INF/classes/ File rootDir = new File(path); //Start parsing the folder - component scanning begins try { //Step 1: Scan the class path, parse out all bean instances, and store them in the IOC container (beanFactory) parseFile(rootDir); beanFactory.values().forEach(System.out::println); //Step 2: After step 1, all bean instances have been created, but the dependencies between beans have not been injected (Injection) //This step implements injecting dependencies beanFactory.values().forEach(bean -> { //Get all fields inside the bean Field[] fields = bean.getClass().getDeclaredFields(); //Get the annotation information on each field Arrays.stream(fields) .filter(field -> field.getDeclaredAnnotation(Autowire.class) != null) .forEach(field -> { //Get the name of the type of this field String fieldTypeName = field.getType().getName(); //System.out.println(fieldTypeName); Object filedValue = beanFactory.values().stream().filter(instance -> { return field.getType().isAssignableFrom(instance.getClass()); }).findFirst().orElseThrow(() -> new RuntimeException(fieldTypeName + "Assembly failed!")); try { field.setAccessible(true); field.set(bean, filedValue); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }); }); //Step 3: After the first two steps: all bean instances have been prepared in the IOC container. And the dependencies between bean instances are also injected. //What needs to be implemented in this step is: uri is:/fruit/index What we need to achieve is to map the two identifiers in the uri to specific controller instances and controller methods. //To put it simply, this step needs to be completed to store each Controller in the controllerBeanMap. beanFactory.values().stream() .filter(bean -> bean.getClass().getDeclaredAnnotation(RequestMapping.class) != null) .forEach(bean->{ String requestMapping = bean.getClass().getDeclaredAnnotation(RequestMapping.class).value(); Object controllerBean = bean; //Start analyzing each method in the bean }); //System.out.println(beanFactory); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private static void parseFile(File file) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { if (file.exists()) { if (file.isDirectory()) { //Get all subdirectories File[] childFiles = file.listFiles(); for (File childFile : childFiles) { parseFile(childFile); } } else { String absPath = file.getAbsolutePath(); //System.out.println(absPath); String fullClassPath = absPath.substring(path.length()); //System.out.println(fullClassPath); if (fullClassPath.endsWith(".class")) { String fullClassPathName = fullClassPath.substring(0, fullClassPath.length() - ".class".length()); //System.out.println(fullClassPathName); String fullClassName = fullClassPathName.replaceAll("\", "."); //System.out.println(fullClassName); Class<?> clazz = Class.forName(fullClassName); //System.out.println(clazz.toString()); if (clazz.toString().startsWith("class")) { //Exclude interfaces and annotations...., only care about class if (!Modifier.isAbstract(clazz.getModifiers())) { //Exclude abstract classes Optional<Annotation> optional = Arrays.stream(clazz.getDeclaredAnnotations()).filter(annotation -> { return (annotation instanceof Controller || annotation instanceof Service || annotation instanceof Repository); }).findFirst(); if (!optional.isEmpty()) { Object bean = clazz.getDeclaredConstructor().newInstance(); beanFactory.put(fullClassName, bean); } } } } } } } }
The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139,158 people are learning the system