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 "";
}
 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.METHOD})//在方法上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
String value() default "";
}
 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.FIELD})//代表注解的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Quatifier {
String value() default "";
}
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{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()

      

 package com.cn.servlet;

 import java.io.File;
import java.io.IOException;
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.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
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.annotation.Service;
import com.cn.controller.SpringmvcController; /**
* Servlet implementation class DispatcherServlet
*/
@WebServlet("/DispatcherServlet")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
List<String> packageNames=new ArrayList<String>();
//所有类的实例 key是注解的value, value是所有类的实例
Map<String,Object> instanceMap=new HashMap<String,Object>(); Map<String,Object> handerMap=new HashMap<String,Object>();
/**
* @see HttpServlet#HttpServlet()
*/
public DispatcherServlet() {
super();
} /**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
//包扫描,获取包中的文件
scanPackage("com.cn"); try {
filterAndInstance();
} catch (Exception e) {
e.printStackTrace();
}
//建立一个映射关系
handerMap(); ioc();//实现注入
}
private void scanPackage(String basePackage){
URL url=this.getClass().getClassLoader().getResource("/"+replaceTo(basePackage));//将所有.转义获取对应的路径 String pathfile=url.getFile();
File file=new File(pathfile); String[] files=file.list();
for (String path : files) {
File eachFile= new File(pathfile+path);//有点问题
if(eachFile.isDirectory()){
scanPackage(basePackage+"."+eachFile.getName());
}else{ packageNames.add(basePackage+"."+eachFile.getName());
} } }
private String replaceTo(String path){
return path.replaceAll("\\.","/");
}
public void handerMap(){
if(instanceMap.size()<=0)
return;
for(Map.Entry<String, Object> entry:instanceMap.entrySet()){
if(entry.getValue().getClass().isAnnotationPresent(Controller.class)){
Controller controller=(Controller)entry.getValue().getClass().getAnnotation(Controller.class);
String ctvalue= controller.value();
Method[] methods=entry.getValue().getClass().getMethods();
for(Method method:methods){
if(method.isAnnotationPresent(RequestMapping.class)){
RequestMapping rm= (RequestMapping)method.getAnnotation(RequestMapping.class);
String rmvalue=rm.value();
handerMap.put("/"+ctvalue+"/"+rmvalue,method);
}else{
continue;
}
}
}else{
continue;
} }
}
public void ioc(){
if(instanceMap.isEmpty())return; for(Map.Entry<String, Object> entry:instanceMap.entrySet()){
Field[] fields= entry.getValue().getClass().getDeclaredFields();//拿到类里面的属性
for (Field field : fields) {
field.setAccessible(true);
if(field.isAnnotationPresent(Quatifier.class)){
Quatifier qf=(Quatifier)field.getAnnotation(Quatifier.class);
String value= qf.value(); field.setAccessible(true);
try {
field.set(entry.getValue(), instanceMap.get(value));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} }
public void filterAndInstance() throws Exception{
if(packageNames.size()<=0){
return;
}
for (String classname : packageNames) {
Class ccName=Class.forName(classname.replace(".class",""));
if(ccName.isAnnotationPresent(Controller.class)){
Object instance= ccName.newInstance();
Controller an= (Controller) ccName.getAnnotation(Controller.class);
String key=an.value();
instanceMap.put(key,instance);
}else if(ccName.isAnnotationPresent(Service.class)){
Object instance= ccName.newInstance();
Service an= (Service) ccName.getAnnotation(Service.class);
String key=an.value();
instanceMap.put(key,instance);
}else{
continue;
}
}
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String url= request.getRequestURI();
String context=request.getContextPath();
String path=url.replace(context,"");
Method method =(Method) handerMap.get(path);
SpringmvcController controller=(SpringmvcController) instanceMap.get(path.split("/")[1]);
try {
method.invoke(controller, new Object[]{request,response,null});
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} }

第三步:

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过程的更多相关文章

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

    首先明白 动态代理和静态代理的区别: 静态代理:①持有被代理类的引用  ② 代理类一开始就被加载到内存中了(非常重要) 动态代理:JDK中的动态代理中的代理类是动态生成的.并且生成的动态代理类为$Pr ...

  2. 纯手写Myatis框架

    1.接口层-和数据库交互的方式 MyBatis和数据库的交互有两种方式: 使用传统的MyBatis提供的API: 使用Mapper接口: 2.使用Mapper接口 MyBatis 将配置文件中的每一个 ...

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

    超级简单的评分功能,分为四个步骤轻松搞定: 第一步: 引入jquery文件:这里我用百度CDN的jquery: <script src="http://apps.bdimg.com/l ...

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

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

  5. 超级简单的jQuery纯手写五星评分效果

    超级简单的评分功能,分为四个步骤轻松搞定: 第一步: 引入jquery文件:这里我用百度CDN的jquery: <script src="http://apps.bdimg.com/l ...

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

    建表啥的只点点鼠标,太外行了,不如来看看我的纯手写,让表从无到有一系列:还有存储过程临时表,不间断的重排序: 一:建数据库 create Database Show on primary ( name ...

  7. 纯手写SpringMVC到SpringBoot框架项目实战

    引言 Spring Boot其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置. 通过这种方式,springboot ...

  8. 纯手写SpringMVC框架,用注解实现springmvc过程

    闲话不多说,直接上代码! 1.第一步,首先搭建如下架构,其中,annotation中放置自己编写的注解,主要包括service controller qualifier RequestMapping ...

  9. 腾讯T8纯手写66个微服务架构设计模式,全部学会真的“变强”了

    微服务的概念虽然直观易懂,但“细节是魔鬼”,微服务在实操落地的环节中存在诸多挑战.我们在为企业提供PaaS.人工智能.云原生平台等数字化转型解决方案时也发现,企业实现云原生,并充分利用PaaS能力的第 ...

随机推荐

  1. MySQL 编译安装并且开启DEBUG模式

    因为想分析下mysql中一些操作的内部执行过程,单纯的看源码太枯燥了,所以决定结合mysql的执行过程来分析,mysql作为一款成熟的数据库软件,在设计的时候就考虑到了调试的问题,只是想开启调试模式的 ...

  2. 懵逼的闭包--for循环(转)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. ORACLE的DUAL表及DB2的SYSIBM.SYSDUMMY1

    在ORACLE中,数据库用户通过访问DUAL表获取一些系统信息:DB2中,相应的表为SYSIBM.SYSDUMMY1表 ORACE中举例: SELECT SYSDATE FROM DUAL;获取当前日 ...

  4. Android平台下OpenCV移植与使用---基于C/C++

    在<Android Studio增加NDK代码编译支持--Mac环境>和<Mac平台下Opencv开发环境搭建>两篇文章中,介绍了如何使用NDK环境和Opencv环境搭建与测试 ...

  5. LeetCode之404. Sum of Left Leaves

    ------------------------------------------------------------------- 分两种情况: 1.当前节点拥有左孩子并且左孩子是叶子节点:左孩子 ...

  6. python初学杂记

    python常用命令: 1.python 或者 python3  打开交互式python解释器 2.python hello.py   通过命令提示符运行python脚本 交互式python解释器常用 ...

  7. Android root + 修改host

    1.使用KingRoot下载手机版,安装后进行Root处理. 2.下载 RE文件管理器,安装后,打开应用,进入etc,找到host, 勾选,菜单中选择 以文本方式编辑,修改好之后,按返回键 ,提示保存 ...

  8. 登录oracle数据库提示账户锁定解决方法

    问题再现: 由于更改了oracle账户的密码,退出重新连接oracle出现了账户被锁定的情况. 请了百度君出来卸载一下,问题已解决. 在cmd下:sqlplus /nolog 然后:以dba身份登录: ...

  9. Leetcode Candy

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  10. tornado 学习笔记8 模板以及UI

          Tornado 包含一个简单.快速而且灵活的模板语言.       Tornado同样可以使用任何其他的python模板语言,虽然没有集成这些模板语言进RequestHandler.ren ...