纯手写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 @Documented
12 public @interface RequestMapping {
13     String value() default "";
14 }

 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 @Documented
12 public @interface Quatifier {
13     String value() default "";
14 }

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 Service {
    String value() default "";
}

以后我们需要什么注解都可以自己创建, 直接右键创建一个注解就可以了。这里是模仿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{[email protected], [email protected], [email protected]1d90a3}

      ③建立一个映射关系(地址映射,不同的地址映射到不同的方法):    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= 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=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= 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 }

第三步:

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;
    }

}
时间: 2024-12-30 17:08:34

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

纯手写SpringBoot框架之注解方式启动SpringMVC容器

使用Java语言创建Tomcat容器,并且通过Tomcat执行Servlet,接下来,将会使用Java语言在SpringBoot创建内置Tomcat,使用注解方式启动SpringMVC容器. 代码实现.1.pom.xml文件,需要依赖的jar包. <dependencies> <!--Java语言操作Tomcat--> <dependency> <groupId>org.apache.tomcat.embed</groupId> <arti

springmvc 动态代理 JDK实现与模拟JDK纯手写实现。

首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用  ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Proxy0 静态代理实例1.创建一个接口: package proxy; public interface People { public void zhaoduixiang()throws Throwable; } 2.创建一个实现类,张三,张三能够吃饭,张三可以找对象 package proxy;

vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源占用少,无依赖,多平台的javascript滚动插件.iScroll不仅仅是 滚动.它可以处理任何需要与用户进行移动交互的元素.在你的项目中包含仅仅4kb大小的iScroll,你的项目便拥有了滚动,缩放,平移,无限滚动,视差滚动,旋转功能.iScroll的强大毋庸置疑,本人也非常欢迎大家使用iScr

纯手写wcf代码,wcf入门,wcf基础教程

<pre name="code" class="cpp">/* 中颖EEPROM,使用比较方便,但有个注意点,就是每次无论你写入 什么数据或者在哪个地址写数据,都需要将对 对应的块擦除,擦 除后才能写入成功. */ #define SSPWriteFlag 0x5A #define SSPEraseFlag 0xA5 //数据区 扇形区1 #define ADDR_START1 (uint16)0x100 //数据存储区起始地址 #define ADDR

SQL纯手写创建数据库到表内内容

建表啥的只点点鼠标,太外行了,不如来看看我的纯手写,让表从无到有一系列:还有存储过程临时表,不间断的重排序: 一:建数据库 1create Database Show 2 on 3 primary 4 ( 5 name= Show_data , 6 filename= 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQLEXPRESS\MSSQL\DATA\Show.mdf' , 7 size=10MB, 8 maxsize=UNLIMITED,

qt之旅-1纯手写Qt界面

通过手写qt代码来认识qt程序的构成,以及特性.设计一个查找对话框.下面是设计过程 1 新建一个empty qt project 2 配置pro文件 HEADERS += Find.h QT += widgets SOURCES += Find.cpp main.cpp 3 编写对话框的类 代码如下: //Find.h #ifndef FIND_H #define FIND_H #include <QDialog> class QCheckBox; class QLabel; class QL

简易-五星评分-jQuery纯手写

超级简单的评分功能,分为四个步骤轻松搞定: 第一步: 引入jquery文件:这里我用百度CDN的jquery: <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> 第二步: 写HTML代码:这里的星星我用的是符号的星星,也可以做成图片,用2张背景图片进行切换: 1 <div class="score_star"> 2 <i

Spring Boot2.0之纯手写框架

框架部分重点在于实现原理,懂原理! 废话不多说,动手干起来! SpringMVC程序入口? 没有配置文件,Spring 容器是如何加载? 回顾我们之前搭建Spring Boot项目使用的pom 引入的依赖需要parent,其作用是支持依赖 快速整合框架 不需要写版本号 还有就是web组件,自动引入springmvc spring-web spring-beans  等等都依赖进来了 SpringBoot是一个快速整合第三方框架,简化XML配置,完全采用注解.内置HTTP服务器(tomcat.je

纯手写springIOC

大家好啊- 那么今天来带大家写一下spring的ioc. 其实也很简单,首先我们明白两点,java解析xml和java的反射机制,因为ioc就是主要是基于这两个来实现,今天只是简单的来大家实现下. 废话不多说直接上代码. 1.首先加入maven依赖我们这里用到的xml解析是dem4j,先看下项目结构吧. 2.导入maven依赖 1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns=&qu