簡單mvc---模擬Springmvc

一、註解篇

Auwowritedhtml

package org.aaron.mvc.annaotation;

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

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented    
public @interface AaronAutowrited {

    String value() default "";
}

 

Controllerjava

package org.aaron.mvc.annaotation;

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

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented    
public @interface AaronController {

    String value() default "";
}

 

RequestMappingspring

package org.aaron.mvc.annaotation;

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

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented    
public @interface AaronRequestMapping {

    String value() default "";
}

RequestParam數組

package org.aaron.mvc.annaotation;

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

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented    
public @interface AaronRequestParam {

    String value() default "";
}

Servicemvc

package org.aaron.mvc.annaotation;

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

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented    
public @interface AaronService {

    String value() default "";
}

二、DispatcherServlet

package org.aaron.mvc.servlet;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aaron.mvc.annaotation.AaronAutowrited;
import org.aaron.mvc.annaotation.AaronController;
import org.aaron.mvc.annaotation.AaronRequestMapping;
import org.aaron.mvc.annaotation.AaronRequestParam;
import org.aaron.mvc.annaotation.AaronService;
import org.omg.CORBA.Request;

public class DispatcherServlet extends HttpServlet {

    List<String> classNames = new ArrayList<String>();// 全類名路徑
                                                        // //org.aaron.mvc.service.impl+類名
    
    Map<String,Object> beans = new HashMap<>();
    
    Map<String,Object> handlerMap = new HashMap<>();
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public void init(ServletConfig config) {
        // ioc
        // 掃描全部的bean----->掃描全部的class文件
        scanPackage("org.aaron"); // spring的作法是寫在配置文件中
        // 根據類建立對象
        doInstance();
        doIoc();
        buildUrlMapping();//根據url 創建關係  method
    }

    // 掃描文件
    private void scanPackage(String basePackage) {
        URL url = this.getClass().getClassLoader().getResource("/" + basePackage.replaceAll("\\.", "/"));// 獲取工做空間的編譯路徑
        System.err.println(url);
        String fileStr = url.getFile();
        File file = new File(fileStr);// 拿到目錄下的文件和文件夾
        String[] filesStr = file.list(); // Aaron
        for (String path : filesStr) {

            File filePath = new File(fileStr + path);// org.aaron.mvc
            if (filePath.isDirectory()) {// 判斷是文件仍是文件夾 文件夾 遞歸繼續找

                scanPackage(basePackage + "." + path);
            } else {

                classNames.add(basePackage + "." + filePath.getName());// org.aaron.mvc.xxx.xxxx.class
            }
        }
    }

    // 根據掃描的類名 實例化
    private void doInstance() {
        if (classNames.size() <= 0) {
            System.err.println("掃描失敗");
            return;
        }
        // 遍歷 掃描到class文件
        for (String className : classNames) {
            String cn = className.replace(".class", "");
            try {
                Class<?> clazz = Class.forName(cn); // 獲取到org.aaron.
                if (clazz.isAnnotationPresent(AaronController.class)) {// 判斷是否是有控制場註解
                    Object instance = clazz.newInstance();// 建立類 實例化的對象
                    AaronRequestMapping requestMapping = clazz.getAnnotation(AaronRequestMapping.class);//拿到 mapping 註解
                    String rm = requestMapping.value();//獲取到mapping的value        
                    beans.put(rm, instance);// 
                }else if (clazz.isAnnotationPresent(AaronService.class)){
                    
                    AaronService aaronService = clazz.getAnnotation(AaronService.class);
                    Object instance = clazz.newInstance();
                    beans.put(aaronService.value(),instance);// 
                }else{
                    continue;
                }
                
                
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
    //把service 注入到Controller
    public void doIoc(){
        if(beans.entrySet().size()<=0){
            
            System.err.println("沒有實例化的類");
        }
        //遍歷map的實例化的類
        for(Map.Entry<String, Object> entry: beans.entrySet()){
            Object instace = entry.getValue();
            Class<?> clazz = instace.getClass();
            if(clazz.isAnnotationPresent(AaronController.class)){
                
                Field[] fields =clazz.getDeclaredFields();
                for(Field field : fields){
                    if(field.isAnnotationPresent(AaronAutowrited.class)){//判斷當前遍歷是否有註解
                        AaronAutowrited aaronAutowrited = field.getAnnotation(AaronAutowrited.class);
                        String key = aaronAutowrited.value();//獲取到 註解的value
                        field.setAccessible(true);//由於是private  沒法修改值
                        try {
                            field.set(instace, beans.get(key));
                        } catch (IllegalArgumentException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }else{
                        continue;
                    }
                    
                }
            }else{
                continue;
            }
            
                    
        }
    }

    private void buildUrlMapping(){
        
        if(beans.entrySet().size()<=0){//沒有類的實例化
            System.err.println("沒有類的實例化");
            return;
        }
        for(Map.Entry<String, Object> entry : beans.entrySet()){
            Object instance = entry.getValue();
            Class<?> clazz = instance.getClass();
            if(clazz.isAnnotationPresent(AaronController.class)){
                
                AaronRequestMapping aaronRequestMapping = clazz.getAnnotation(AaronRequestMapping.class);
                String classPath = aaronRequestMapping.value();//拿到類上的mapping
                Method[] methods = clazz.getMethods();//拿到類的方法
                for(Method method : methods){
                    if(method.isAnnotationPresent(AaronRequestMapping.class)){//判斷了方法上面是否有註解
                        AaronRequestMapping methodMapping = method.getAnnotation(AaronRequestMapping.class);
                        String methodPath = methodMapping.value();//獲取到註解的value
                        handlerMap.put(classPath+methodPath, method);
                        
                    }else{
                        continue;
                    }
                    
                }
            }else{
                continue;
            }
        }
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.err.println("test1");
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //獲取請求路徑 /項目名/ctrl/method
        String uri = req.getRequestURI();
        String content = req.getContextPath();//獲取項目名
        String path = uri.replace(content, "");//ctrl/method
        Method method = (Method)handlerMap.get(path);
        Object instance = (Object)beans.get("/"+path.split("/")[1]);// ctrl
        Object[] agrs = hand(req,resp,method);
        try {
            method.invoke(instance, agrs);
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        super.doPost(req, resp);
    }
    //處理參數
    private static Object[] hand(HttpServletRequest req, HttpServletResponse resp,Method method){
        //拿到當前執行的方法有哪些參數
        Class<?>[] paramClazzs = method.getParameterTypes();
        //根據參數的個數 new一個存放參數的數組
        Object[] args = new Object[paramClazzs.length];
        int arg_i = 0 ;
        int index = 0;
        for(Class<?> paramClazz : paramClazzs){
            if(ServletRequest.class.isAssignableFrom(paramClazz)){
                
                args[arg_i++] = req;
            }
            if(ServletResponse.class.isAssignableFrom(paramClazz)){
                
                args[arg_i++] = resp;
            }
            Annotation[] paramAns = method.getParameterAnnotations()[index];
            if(paramAns.length>0){
                for(Annotation paramAn : paramAns){
                    if(AaronRequestParam.class.isAssignableFrom(paramAn.getClass())){
                        AaronRequestParam rp = (AaronRequestParam)paramAn;
                        args[arg_i++] =  req.getParameter(rp.value());
                        
                    }
                    
                }
                
            }
            index++;
        }
        return args;
        
    }
    

}

三、實戰篇

controller代碼app

package org.aaron.mvc.ctrl;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aaron.mvc.annaotation.AaronAutowrited;
import org.aaron.mvc.annaotation.AaronController;
import org.aaron.mvc.annaotation.AaronRequestMapping;
import org.aaron.mvc.annaotation.AaronRequestParam;
import org.aaron.mvc.service.TestService;

    
@AaronController
@AaronRequestMapping("/Aaron")
public class TestCtrl {

    @AaronAutowrited("TestServiceImpl")
    private TestService service;
    
    @AaronRequestMapping("/query")
    public void query(HttpServletRequest request,HttpServletResponse response,
            @AaronRequestParam("name") String name, @AaronRequestParam("age") String age){
        String result =  service.query(name, age);
        try {
            PrintWriter out;
         
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html; charset=utf-8");
            out = response.getWriter();
     
            out.write(result);
            out.close();
        
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
    
}

service接口ide

package org.aaron.mvc.service;

public interface TestService {

    String query(String name,String age);
}

 

service接口實現ui

package org.aaron.mvc.service.impl;

import org.aaron.mvc.annaotation.AaronService;
import org.aaron.mvc.service.TestService;


@AaronService("TestServiceImpl")
public class TestServiceImpl implements TestService{

    public String query(String name, String age) {
        // TODO Auto-generated method stub
        return "當前用戶:"+name+"年齡"+age ;
    }

}
相關文章
相關標籤/搜索