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. hdfs的读写数据流

    hdfs的读:      首先客户端通过调用fileSystem对象中的open()函数读取他需要的的数据,fileSystem是DistributedFileSystem的一个实例, Distrib ...

  2. php 二维数组按某字段排序

    思路很重要,最好的方法是查询时按这个字段给你排好,把问题丢给数据库,比如  order by age ,如果遇到中文时需要这样写(mysql) 如:select * from category ord ...

  3. [译]:Orchard入门——Orchard控制面板概览

    原文链接:Getting Around the Dashboard 文章内容基于Orchard 1.8版本 Orchard控制面板用于管理网站.改变外观.添加内容以及控制Orchard功能可用性.成功 ...

  4. UITableView在设置contentOffset的同时也reload,造成tableView的contentOffset偏差

    最近在写一个聊天的框架,遇到一个奇葩的问题,就是发送聊天记录的时候(需要tableView上移,显示出最新的记录),增加一条记录无疑需要reload一下(大家都明白的),这是就会出现头疼的问题,页面显 ...

  5. [leetcode] 29. divide two integers

    这道题目一直不会做,因为要考虑的corner case 太多. 1. divisor equals 0. 2. dividend equals 0. 3. Is the result negative ...

  6. 网友分享 调用dll的语音朗读 不能变速,不好

    调用   speeker.dll   这个文件被本人 放在文件里面,若有人需要可以 联系我 需要 mfc100ud.dll msvcr100d.dll 注:可以用D7 自带的ActiveX 里面的控件 ...

  7. Java动态、重写 理解

    相关类: class A ...{ public String show(D obj)...{ return ("A and D"); } public String show(A ...

  8. requirejs的用法(二)

    这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的 ...

  9. Linux学习总结

    1.软链接和硬链接 ln 命令可用来创建硬链接或是符号链接.它的使用方式有两种. ln file link 用来创建硬链接 ln -s item link 用来创建符号链接,这里的item可以是文件也 ...

  10. Django分析之三级下拉菜单选择省/市/县

    今天遇到了一个一直想做却没有机会去做的功能,今天完成了便记录下来. 那这次是具体是个什么功能呢?其实还是很简单的效果,就是在用户注册的时候可以选择省/市/县,很简单的一个小功能. 那现在就开始了~首先 ...