雄爷的SpringMVC源码

原创
2019/04/28 01:04
阅读数 391

直接上干货

public class DispatcherServlet extends HttpServlet {
   
   private Properties contextConfigProperties = new Properties();
   
   private List<String> classNames = new ArrayList<>();
   
   private Map<String, Object> ioc = new HashMap<String, Object>();
   
   private Map<String, Method> handlerMappings = new HashMap<>();
   
    /**
    * 
    */
   private static final long serialVersionUID = 1L;

   @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       try {
          dispatcher(req,resp);
      } catch (Exception e) {
         resp.getWriter().write("500 Server has an error"+Arrays.toString(e.getStackTrace()));
      } 
    }

    private void dispatcher(HttpServletRequest req, HttpServletResponse resp) throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
      if (this.handlerMappings.isEmpty()) {
         return;
      }
      
      String url = req.getRequestURI();
      
      String contextPath = req.getContextPath();
      
      url.replace(contextPath, "").replaceAll("/+", "/");
      
      if (!this.handlerMappings.containsKey(url)) {
         resp.getWriter().write("404 Page Not Found!    ");
         return;
      }
      
      Method method = this.handlerMappings.get(url);
      
      Map<String,String[]> parameterMap = req.getParameterMap();
      
      String beanName = this.lowerFirstLetter(method.getDeclaringClass().getSimpleName());
      
      Object obj = this.ioc.get(beanName);
      
      if (!parameterMap.containsKey("name")) {
         resp.getWriter().write("handerMapping Not Found!");
         return;
      }
      
      method.invoke(obj, new Object[] {req,resp,parameterMap.get("name")[0]});
   }

   @Override
    public void init(ServletConfig config) throws ServletException {
       //加载配置
        loadConfig(config.getInitParameter("contextConfigLocation"));
        //扫描指定包下的所有类
        scannerClass(this.contextConfigProperties.getProperty("scanPackage"));
        //初始化容器
        initIoc();
        //自动注入
        autoWiredInstance();
        //初始化处理映射
        initHanderMapping();
        
        System.out.println("mvc init over...");
    }

   private void initHanderMapping() {
      if (this.ioc.isEmpty()) {
         return;
      }
      try {
         for (Map.Entry<String, Object> en : this.ioc.entrySet()) {
            boolean present = en.getValue().getClass().isAnnotationPresent(Controller.class);
            if (present) {
               StringBuffer baseUrl = new StringBuffer();
               RequestMapping requestMapping = en.getValue().getClass().getAnnotation(RequestMapping.class);
               baseUrl.append(requestMapping.value());
               
               Method[] methods = en.getValue().getClass().getMethods();
               
               for (Method method : methods) {
                  if (method.isAnnotationPresent(RequestMapping.class)) {
                     RequestMapping mapping = method.getAnnotation(RequestMapping.class);
                     String fullUrl = ("/"+baseUrl.append("/").append(mapping.value().trim()).toString()).replaceAll("/+", "/");
                     this.handlerMappings.put(fullUrl, method);
                  }
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      } 
   }

   private void autoWiredInstance() {
      if (this.ioc.isEmpty()) {
         return;
      }
      
      try {
         for (Map.Entry<String, Object> en : this.ioc.entrySet()) {
            Field[] fields = en.getValue().getClass().getDeclaredFields();
            for (Field field : fields) {
               if (field.isAnnotationPresent(Autowired.class)) {
                  Autowired autowired = field.getAnnotation(Autowired.class);
                  String beanName = autowired.value();
                  if ("".equals(beanName)) {
                     beanName = field.getType().getName();
                  }
                  
                  field.setAccessible(true);
                  
                  field.set(en.getValue(), this.ioc.get(beanName));
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      } 
   }

   private void initIoc() {
      if (this.classNames.isEmpty()) {
         return;
      }
      
      try {
         for (String className : classNames) {
            Class<?> clazz = Class.forName(className);
            if (clazz.isAnnotationPresent(Controller.class)||clazz.isAnnotationPresent(Service.class)) {
               Object newInstance = clazz.newInstance();
               String simpleName = lowerFirstLetter(clazz.getSimpleName());
               if (clazz.getAnnotation(Controller.class)!=null) {
                  String value = clazz.getAnnotation(Controller.class).value();
                  if ("".equals(value.trim())) {
                     this.ioc.put(simpleName, newInstance);
                  }else {                      
                     this.ioc.put(value, newInstance);
                  }
               }else if (clazz.getAnnotation(Service.class)!=null) {
                  String value = clazz.getAnnotation(Service.class).value();
                  handleAnnotation(clazz,value, newInstance);
               }else if (clazz.getAnnotation(Dao.class)!=null) {
                  String value = clazz.getAnnotation(Dao.class).value();
                  handleAnnotation(clazz,value, newInstance);
               }else {
                  this.ioc.put(simpleName, clazz.newInstance());                
               }
            }else {
               continue;
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   private void handleAnnotation(Class<?> clazz,String annotationValue, Object newInstance) throws Exception {
      if ("".equals(annotationValue.trim())) {
         Class<?>[] interfaces = clazz.getInterfaces();
         for (Class<?> i : interfaces) {
            if (this.ioc.containsKey(i.getName())) {
               throw new Exception("the beanName:"+i.getName()+",has samed");
            }
            this.ioc.put(i.getName(), newInstance);
         }
      }else {                      
         this.ioc.put(annotationValue, newInstance);
      }
   }

   private void scannerClass(String scanPackage) {
      URL url = this.getClass().getClassLoader().getResource(File.separator+scanPackage.replaceAll(".", File.separator));
      
      File dir = new File(url.getFile());
      
      for (File file : dir.listFiles()) {
         if (file.isDirectory()) {
            scannerClass(scanPackage+"."+file.getName());
         }else {
            if (!file.getName().contains(".class")) {
               continue;
            }
            String className = (scanPackage+"."+file.getName().replaceAll("class", "")).trim();
            this.classNames.add(className);
         }
      }
   }

   private void loadConfig(String initParameter) {
      InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(initParameter);
      
      try {
         this.contextConfigProperties.load(inputStream);
      } catch (IOException e) {
         // TODO Auto-generated catch block 
         e.printStackTrace();
      } finally {
         if (inputStream!=null) {
            try {
               inputStream.close();
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
         }
      }
   }
   
   private String lowerFirstLetter(String name) {
      char[] chars = name.toCharArray();
      chars[0] += 32;
      return String.valueOf(chars);
   }
}
展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部