首页 > 代码库 > 纯手写SpringMVC架构,用注解实现springmvc过程(动脑学院Jack老师课后自己练习的体会)

纯手写SpringMVC架构,用注解实现springmvc过程(动脑学院Jack老师课后自己练习的体会)

1、第一步,首先搭建如下架构,其中,annotation中放置自己编写的注解,主要包括service controller qualifier RequestMapping

技术分享

第二步:完成对应的annotation:

package com.cn.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)//这是代表运行的时候启动@Documented	public @interface Controller {	String value() default "";}

 

技术分享
 1 package com.cn.annotation; 2  3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8  9 @Target({ElementType.METHOD})//在方法上的注解10 @Retention(RetentionPolicy.RUNTIME)11 @Documented12 public @interface RequestMapping {13     String value() default "";14 }
View Code

 

技术分享
 1 package com.cn.annotation; 2  3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8  9 @Target({ElementType.FIELD})//代表注解的注解10 @Retention(RetentionPolicy.RUNTIME)11 @Documented12 public @interface Quatifier {13     String value() default "";14 }
View Code
技术分享
package com.cn.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Service {    String value() default "";}
View Code

以后我们需要什么注解都可以自己创建, 直接右键创建一个注解就可以了。这里是模仿springmvc,所以jack老师就任性的创建了几个原来springmvc几个相同的注解

2、第二步:编写对应的servlet类,记得勾选init()方法,用来进行相应的实例化和注解反转控制。

        ① 进行包扫描,就是初始化的时候先将整个项目中的包进行扫描,扫描各个文件分别存起来。

           scanPackage("com.cn");//自己的项目,测试用的 所以 扫描包函数的地址写死了

       存在  List<String> packageNames=new ArrayList<String>();其中都是这样:com.cn.annotation.Controller.class ,com.cn.annotation.Quatifier.class, com.cn.annotation.RequestMapping.class,有.class后缀。

      ②过滤和实例化 :由于已经将所有的文件都存在了packageNames中了,那么我们必须将对应的Controller实例化才可以进行相应函数调用,然后其中的所有文件并不一定都是对应的controller文件,所以要进行相应的过滤和处理

          filterAndInstance();

       过滤后的结果保存在:  Map<String,Object> instanceMap=new HashMap<String,Object>();

       其中 String是注解的value, Object是所对应类的实例

          比如:我项目中DEBUG结果instanceMap{dongnao=com.cn.controller.SpringmvcController@7a141541, MyServiceImpl=com.cn.service.impl.MyServiceImpl@3c7f9d04, SpringmvcServiceImpl=com.cn.service.impl.SpringmvcServiceImpl@5e1d90a3}

      ③建立一个映射关系(地址映射,不同的地址映射到不同的方法):    handerMap();

      结果: Map<String,Object> handerMap=new HashMap<String,Object>();

      实例:{/dongnao/select=public java.lang.String com.cn.controller.SpringmvcController.select(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String), /dongnao/delet=public java.lang.String com.cn.controller.SpringmvcController.delet(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String), /dongnao/insert=public java.lang.String com.cn.controller.SpringmvcController.insert(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String), /dongnao/update=public java.lang.String com.cn.controller.SpringmvcController.update(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String)}

      ④ 反转控制,

       根据注解,把service中的注入到controller中的service;

         void ioc()

      

技术分享
  1 package com.cn.servlet;  2   3 import java.io.File;  4 import java.io.IOException;  5 import java.lang.reflect.Field;  6 import java.lang.reflect.InvocationTargetException;  7 import java.lang.reflect.Method;  8 import java.net.URL;  9 import java.util.ArrayList; 10 import java.util.HashMap; 11 import java.util.List; 12 import java.util.Map; 13  14 import javax.servlet.ServletConfig; 15 import javax.servlet.ServletException; 16 import javax.servlet.annotation.WebServlet; 17 import javax.servlet.http.HttpServlet; 18 import javax.servlet.http.HttpServletRequest; 19 import javax.servlet.http.HttpServletResponse; 20  21 import com.cn.annotation.Controller; 22 import com.cn.annotation.Quatifier; 23 import com.cn.annotation.RequestMapping; 24 import com.cn.annotation.Service; 25 import com.cn.controller.SpringmvcController; 26  27  28 /** 29  * Servlet implementation class DispatcherServlet 30  */ 31 @WebServlet("/DispatcherServlet") 32 public class DispatcherServlet extends HttpServlet { 33     private static final long serialVersionUID = 1L; 34     List<String> packageNames=new ArrayList<String>();  35     //所有类的实例 key是注解的value, value是所有类的实例 36     Map<String,Object> instanceMap=new HashMap<String,Object>();  37      38     Map<String,Object> handerMap=new HashMap<String,Object>();  39     /** 40      * @see HttpServlet#HttpServlet() 41      */ 42     public DispatcherServlet() { 43         super(); 44     } 45  46     /** 47      * @see Servlet#init(ServletConfig) 48      */ 49     public void init(ServletConfig config) throws ServletException { 50             //包扫描,获取包中的文件 51         scanPackage("com.cn"); 52          53         try { 54             filterAndInstance(); 55         } catch (Exception e) { 56             e.printStackTrace(); 57         } 58         //建立一个映射关系 59         handerMap(); 60          61         ioc();//实现注入 62     } 63     private void scanPackage(String basePackage){ 64         URL url=this.getClass().getClassLoader().getResource("/"+replaceTo(basePackage));//将所有.转义获取对应的路径 65          66         String pathfile=url.getFile(); 67         File file=new  File(pathfile); 68          69         String[] files=file.list(); 70         for (String path : files) { 71             File eachFile= new File(pathfile+path);//有点问题 72             if(eachFile.isDirectory()){ 73                 scanPackage(basePackage+"."+eachFile.getName()); 74             }else{ 75  76                 packageNames.add(basePackage+"."+eachFile.getName()); 77             } 78              79         } 80          81     } 82     private String replaceTo(String  path){ 83         return path.replaceAll("\\.","/"); 84     } 85     public void handerMap(){ 86         if(instanceMap.size()<=0) 87             return; 88         for(Map.Entry<String, Object> entry:instanceMap.entrySet()){ 89             if(entry.getValue().getClass().isAnnotationPresent(Controller.class)){ 90                 Controller controller=(Controller)entry.getValue().getClass().getAnnotation(Controller.class); 91                 String ctvalue=http://www.mamicode.com/ controller.value(); 92                 Method[] methods=entry.getValue().getClass().getMethods(); 93                 for(Method method:methods){ 94                     if(method.isAnnotationPresent(RequestMapping.class)){ 95                         RequestMapping rm= (RequestMapping)method.getAnnotation(RequestMapping.class); 96                         String rmvalue=http://www.mamicode.com/rm.value(); 97                         handerMap.put("/"+ctvalue+"/"+rmvalue,method); 98                     }else{ 99                         continue;100                     }101                 }102             }else{103                 continue;104             }   105             106         }107     }108     public void ioc(){109         if(instanceMap.isEmpty())return;110         111         for(Map.Entry<String, Object> entry:instanceMap.entrySet()){112             Field[] fields=    entry.getValue().getClass().getDeclaredFields();//拿到类里面的属性113             for (Field field : fields) {114                 field.setAccessible(true);115                 if(field.isAnnotationPresent(Quatifier.class)){116                     Quatifier    qf=(Quatifier)field.getAnnotation(Quatifier.class);117                     String value=http://www.mamicode.com/ qf.value();118                     119                     field.setAccessible(true);120                     try {121                         field.set(entry.getValue(), instanceMap.get(value));122                     } catch (IllegalArgumentException e) {123                         e.printStackTrace();124                     } catch (IllegalAccessException e) {125                         e.printStackTrace();126                     }127                 }128             }129         }130         131     }132     public void filterAndInstance() throws Exception{133         if(packageNames.size()<=0){134             return;135         }136         for (String classname : packageNames) {137             Class ccName=Class.forName(classname.replace(".class",""));138             if(ccName.isAnnotationPresent(Controller.class)){139                 Object instance=     ccName.newInstance();140                 Controller an= (Controller) ccName.getAnnotation(Controller.class);141                 String key=an.value();142                 instanceMap.put(key,instance);143             }else if(ccName.isAnnotationPresent(Service.class)){144                 Object instance=     ccName.newInstance();145                 Service an= (Service) ccName.getAnnotation(Service.class);146                 String key=an.value();147                 instanceMap.put(key,instance);148             }else{149                 continue;150             }151         }152     }153     /**154      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)155      */156     protected void doGet(HttpServletRequest request,157             HttpServletResponse response) throws ServletException, IOException {158         this.doPost(request, response);159     }160 161     /**162      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)163      */164     protected void doPost(HttpServletRequest request,165             HttpServletResponse response) throws ServletException, IOException {166         String url= request.getRequestURI();167         String context=request.getContextPath();168         String path=url.replace(context,"");169         Method method    =(Method) handerMap.get(path);170         SpringmvcController controller=(SpringmvcController) instanceMap.get(path.split("/")[1]); 171         try {172             method.invoke(controller, new Object[]{request,response,null});173         } catch (IllegalAccessException e) {174             e.printStackTrace();175         } catch (IllegalArgumentException e) {176             e.printStackTrace();177         } catch (InvocationTargetException e) {178             e.printStackTrace();179         }180     }181 182 }
View Code

第三步:

controller中的代码:

package com.cn.controller;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.cn.annotation.Controller;import com.cn.annotation.Quatifier;import com.cn.annotation.RequestMapping;import com.cn.service.impl.MyService;import com.cn.service.impl.SpringmvcService;@Controller("dongnao")public class SpringmvcController {    @Quatifier("MyServiceImpl")    MyService myservice;        @Quatifier("SpringmvcServiceImpl")    SpringmvcService smservice;        @RequestMapping("insert")    public String  insert(HttpServletRequest request,            HttpServletResponse response,String param){        System.out.println(request.getRequestURI()+"insert");        myservice.insert(null);                smservice.insert(null);        return null;    }    @RequestMapping("delet")    public String  delet(HttpServletRequest request,            HttpServletResponse response,String param){        myservice.delet(null);                smservice.delet(null);        return null;    }        @RequestMapping("select")    public String  select(HttpServletRequest request,            HttpServletResponse response,String param){        myservice.select(null);                smservice.select(null);        return null;    }        @RequestMapping("update")    public String  update(HttpServletRequest request,            HttpServletResponse response,String param){        myservice.update(null);                smservice.update(null);        return null;    }        }
package com.cn.service.impl;import java.util.Map;import com.cn.annotation.Service;public interface SpringmvcService {    int insert(Map map);        int delet(Map map);        int update(Map map);        int select(Map map);}
package com.cn.service.impl;import java.util.Map;import com.cn.annotation.Service;@Service("MyServiceImpl")public class MyServiceImpl implements MyService {    public int insert(Map map) {        System.out.println("MyServiceImpl:"+"insert");        return 0;    }    public int delet(Map map) {        System.out.println("MyServiceImpl:"+"delet");        return 0;    }    public int update(Map map) {        System.out.println("MyServiceImpl:"+"update");        return 0;    }    public int select(Map map) {        System.out.println("MyServiceImpl:"+"select");        return 0;    }}
package com.cn.service.impl;import java.util.Map;import com.cn.annotation.Service;public interface SpringmvcService {    int insert(Map map);        int delet(Map map);        int update(Map map);        int select(Map map);}
package com.cn.service.impl;import java.util.Map;import com.cn.annotation.Service;@Service("SpringmvcServiceImpl")public class SpringmvcServiceImpl implements SpringmvcService {    public int insert(Map map) {        System.out.println("SpringmvcServiceImpl:"+"insert");        return 0;    }    public int delet(Map map) {        System.out.println("SpringmvcServiceImpl:"+"delet");        return 0;    }    public int update(Map map) {        System.out.println("SpringmvcServiceImpl:"+"update");        return 0;    }    public int select(Map map) {        System.out.println("SpringmvcServiceImpl:"+"select");        return 0;    }}

 

纯手写SpringMVC架构,用注解实现springmvc过程(动脑学院Jack老师课后自己练习的体会)