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. LeetCode之136. Single Number

    -------------------------------------- 一个数异或它自己会得到0,0异或n会得到n,所以可以用异或来消除重复项. AC代码如下: public class Sol ...

  2. PHP的两种表单数据提交方式

    1 通过隐藏表单提交 //通过隐藏表单提交 if ($_POST['action'] == 'register'){ echo '你提交了数据'; exit(); } ?> <!DOCTY ...

  3. 终端下vim无法输入问题解决

    最近回归vim时发现会偶尔出现vim无法输入,但光标在动的情况,一度怀疑是spf13的问题,后来经搜索,才发现是因为vim下,快捷键 Ctrl+s 的功能是停止输入,在IDE下编程时间长了,都有潜意识 ...

  4. OGG-01820 Could not enable workspace

    状况: OGG replicat进程abend了,查看report显示如下问题: 2016-11-01 16:11:47  ERROR   OGG-01820  Could not enable wo ...

  5. Mac系统 安装SVN

  6. Fzu2124 - 吃豆人 BFS

    Description 吃豆人是一款非常经典的游戏,游戏中玩家控制吃豆人在地图上吃光所有豆子,并且避免被怪物抓住. 这道题没有怪物,将游戏的画面分成n*m的格子,每格地形可能为空地或者障碍物,吃豆人可 ...

  7. 设置R启动时自动加载常用的包或函数

    在我前面的文章(http://www.cnblogs.com/homewch/p/5749850.html)中有提到R可以自定义启动环境,需要修改R安装文件中的ect文件夹下的配置文件Rprofile ...

  8. LINUX内核参数网络相关

    有助于提高网络性能和吞吐量的参数 net.core.somaxconn = 128 已完成连接队列(completed connection queue) (1)三次握手已经完成,但还未被应用层接收( ...

  9. 初识genymotion安装遇上的VirtualBox问题

    想必做过Android开发的都讨厌那慢如蜗牛的 eclipse原生Android模拟器吧! 光是启动这个模拟器都得花上两三分钟,慢慢的用起来手机来调试,但那毕竟不是长久之计,也确实不方便,后来知道了g ...

  10. 设置 tableview 的背景颜色,总是有蒙层

    1.给tableview添加了背景图片后, cell 总是有一层蒙层蒙着,很阴暗. 2.实验以后才发现背景图片被放在了 cell 的后面.