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. python--基础学习(五)参数位置传递、关键字传递、包裹传递及解包裹

    python系列均基于python3.4环境 1.位置传递和关键字传递 代码示例 #位置传递 def fun(a,b,c): print("a: {0}, b: {1}, c: {2}&qu ...

  2. NSString使用stringWithFormat拼接的相关知识

    NSString使用stringWithFormat拼接的相关知识 保留2位小数点 1 2 3 4 //.2代表小数点后面保留2位(2代表保留的数量) NSString *string = [NSSt ...

  3. android系统中自带的一些ThemeStyle

    1 android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen" 布局页面最上面 不会显示  and ...

  4. Pfile VS Spfile (MOS Note 249664.1)

    ============================================================================== Until Oracle 8i DBAs ...

  5. Logging vs NoLogging

    You Asked My Prod environments is like this. Three Node RAC, Active Data guard enabled. There is a p ...

  6. C语言中的强符号与弱符号

    转自:http://blog.csdn.net/astrotycoon/article/details/8008629 一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初 ...

  7. WPF基础知识、界面布局及控件Binding(转)

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  8. Android入门(一):创建Android工程

    开发Android应用过程一般分为三步: 1.创建一个Android工程: 2.在xml布局文件中定义应用所包含的控件: 3.在Java代码中实现业务逻辑. 此文就介绍第一部分,创建一个Android ...

  9. Leetcode Substring with Concatenation of All Words

    You are given a string, S, and a list of words, L, that are all of the same length. Find all startin ...

  10. [Leetcode] Decode Ways

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...