1.首先我们来搭建架构,就建一个普通的javaweb项目就OK了,具体目录如下:

  

  对于小白来说可以细看后面web.xml的配置,对javaweb有点研究可以忽略而过后面的web.xml配置。

2.先上代码,运行起整个项目。再来聊聊思路。

  

  (1).Controller注解
     

package com.wuqi.annotation;
import java.lang.annotation.*;
/**
* Created by wuqi on 2017/3/22.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
String value() default "";
}
     (2).Quatifier注解
    

package com.wuqi.annotation;

import java.lang.annotation.*;

/**
* Created by wuqi on 2017/3/25.
*/
@Target({ ElementType.FIELD }) // 代表注解的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Quatifier {
String value() default "";
}
      (3).RequestMapping注解
     

package com.wuqi.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;
/**
* Created by Shock on 2017/3/22.
*/
@Target({ ElementType.METHOD }) // 在方法上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
String value() default "";
}
(4).Service注解
     

package com.wuqi.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;
/**
* Created by Shock on 2017/3/22.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
String value() default "";
}

--------------------------------------------------------------------------------------------------------------------------

   

     (1).MyService接口
    

package com.wuqi.service.impl;

import java.util.Map;

/**
* Created by wuqi on 2017/3/23.
*/
public interface MyService { int insert(Map map); int delete(Map map); int update(Map map); int select(Map map); }
     (2).MyServiceImpl类
    

package com.wuqi.service.impl;
import com.wuqi.annotation.Service; import java.util.Map;
/**
* Created by wuqi on 2017/3/23.
*/
@Service("MyServiceImpl")
public class MyServiceImpl implements MyService {
@Override
public int insert(Map map) {
System.out.println("MyServiceImpl:" + "insert");
return 0;
} @Override
public int delete(Map map) {
System.out.println("MyServiceImpl:" + "delete");
return 0;
} @Override
public int update(Map map) {
System.out.println("MyServiceImpl:" + "update");
return 0;
} @Override
public int select(Map map) {
System.out.println("MyServiceImpl:" + "select");
return 0;
}
}
      (3).SpringmvcService接口
    

package com.wuqi.service.impl;

import java.util.Map;

/**
* Created by wuqi on 2017/3/23.
*/
public interface SpringmvcService {
int insert(Map map); int delete(Map map); int update(Map map); int select(Map map);
}
   (4).MyServiceImpl类
    

package com.wuqi.service.impl;
import com.wuqi.annotation.Service; import java.util.Map;
/**
* Created by wuqi on 2017/3/23.
*/
@Service("SpringmvcServiceImpl")
public class SpringmvcServiceImpl implements SpringmvcService{
@Override
public int insert(Map map) {
System.out.println("SpringmvcServiceImpl:" + "insert");
return 0;
}
@Override
public int delete(Map map) {
System.out.println("SpringmvcServiceImpl:" + "delete");
return 0;
}
@Override
public int update(Map map) {
System.out.println("SpringmvcServiceImpl:" + "update");
return 0;
}
@Override
public int select(Map map) {
System.out.println("SpringmvcServiceImpl:" + "select");
return 0;
} }

--------------------------------------------------------------------------------------------------------------------------

   

  (1).SpringmvcController类
  

package com.wuqi.controller;
import com.wuqi.annotation.*;
import com.wuqi.service.impl.MyService;
import com.wuqi.service.impl.SpringmvcService; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by wuqi on 2017/3/23.
*/
@Controller("wuqi")
public class SpringmvcController {
@Quatifier("MyServiceImpl")
MyService myService;
@Quatifier("SpringmvcServiceImpl")
SpringmvcService smService; @RequestMapping("insert")
public String insert(HttpServletRequest request, HttpServletResponse response, String param) {
myService.insert(null);
smService.insert(null);
return null;
} @RequestMapping("delete")
public String delete(HttpServletRequest request, HttpServletResponse response, String param) {
myService.delete(null);
smService.delete(null);
return null;
} @RequestMapping("update")
public String update(HttpServletRequest request, HttpServletResponse response, String param) {
myService.update(null);
smService.update(null);
return null;
} @RequestMapping("select")
public String select(HttpServletRequest request, HttpServletResponse response, String param) {
myService.select(null);
smService.select(null);
return null;
}
}

--------------------------------------------------------------------------------------------------------------------------

  

(1).DispatcherServlet类继承 javax.servlet.http.HttpServlet类
  

package com.wuqi.servlet;

import com.wuqi.annotation.*;
import com.wuqi.controller.SpringmvcController;
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.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Created by Shock on 2017/3/23.
*/
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>();
public DispatcherServlet() {
super();
} public void init(ServletConfig config) throws ServletException {
// 包扫描,获取包中的文件
scanPackage("com.wuqi");
try {
filterAndInstance();
} catch (Exception e) {
e.printStackTrace();
}
// 建立映射关系
handerMap();
// 实现注入
ioc();
} private void filterAndInstance() throws Exception {
if (packageNames.size() <= 0) {
return;
}
for (String className : packageNames) {
Class<?> cName = Class.forName(className.replace(".class", "").trim());
if (cName.isAnnotationPresent(Controller.class)) {
Object instance = cName.newInstance();
Controller controller = (Controller) cName.getAnnotation(Controller.class);
String key = controller.value();
instanceMap.put(key, instance);
} else if (cName.isAnnotationPresent(Service.class)) {
Object instance = cName.newInstance();
Service service = (Service) cName.getAnnotation(Service.class);
String key = service.value();
instanceMap.put(key, instance);
} else {
continue;
}
}
} private 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 quatifier = field.getAnnotation(Quatifier.class);
String value = quatifier.value();
field.setAccessible(true);
try {
field.set(entry.getValue(), instanceMap.get(value));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
SpringmvcController wuqi = (SpringmvcController) instanceMap.get("wuqi");
System.out.print(wuqi);
} /**
* 扫描包下的所有文件
*
* @param Package
*/
private void scanPackage(String Package) {
URL url = this.getClass().getClassLoader().getResource("/" + replaceTo(Package));// 将所有的.转义获取对应的路径
String pathFile = url.getFile();
File file = new File(pathFile);
String fileList[] = file.list();
for (String path : fileList) {
File eachFile = new File(pathFile + path);
if (eachFile.isDirectory()) {
scanPackage(Package + "." + eachFile.getName());
} else {
packageNames.add(Package + "." + eachFile.getName());
}
}
} /**
* 建立映射关系
*/
private 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;
} }
} private String replaceTo(String path) {
return path.replaceAll("\\.", "/");
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String url = req.getRequestURI();
String context = req.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[] { req, resp, null });
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

所有的代码已经贴上,还有个web.xml

  

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>com.wuqi.servlet.DispatcherServlet</servlet-class>
</servlet>
<!-- ... -->
<servlet-mapping>
<servlet-name>testServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

  3.好了代码已经贴上了,现在需要来说说思路,因为有代码了,所以用代码来将思路,这样更容易理解代码的含义。之后可以根据自己的程度去试着写。

  •     首先我们需要扫描包中的所有文件(DispatcherServlet -> init(ServletConfig config) -> scanPackage("com.wuqi")),也就是含有注解的文件。然后将该包下的所有文件都存入packageNames集合中。
  •     这时我们拿到了包下所有的文件,但我们只需要含有我们指定注解的那部分文件,因此需要过滤出我们想要的文件即可,并且在过滤的过程中,我们可以将过滤出来的类通过Class.forName来直接实例化并储存起来。存放到instanceMap集合中,并为其设置对应的key值,该key值就是类注解的value。
  • 然后遍历instanceMap集合中的所有对象,获取指定注解的对象,并通过反射获取该对象的所有的方法,遍历所有的方法,将指定注解的方法存入handerMap,key为拼接字符串("/" + 对象变量名 + "/" + 方法名),value为方法(Method)。
  • 然后我们可以遍历instanceMap集合中的所有对象,通过反射获取对象的所有属性值(字段)集合,然后遍历属性值集合,将属性值含有指定注解的,通过Field的set方法为该属性值赋值,这时就将对象注入了。(也就是往Controller中注入Service对象)
  • 最后就可以通过反射的invoke方法调用某个对象的某个方法。(此时对象存于instanceMap,而方法都存于handerMap)

参考链接:

通过注解实现一个简易的Spring mvc框架的更多相关文章

  1. 从零开始实现一个简易的Java MVC框架(三)--实现IOC

    Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency ...

  2. Spring MVC篇一、搭建Spring MVC框架

    本项目旨在搭建一个简单的Spring MVC框架,了解Spring MVC的基础配置等内容. 一.项目结构 本项目使用idea intellij创建,配合maven管理.整体的目录结构如图: 其中ja ...

  3. Spring MVC框架搭建

    Spring MVC篇一.搭建Spring MVC框架 本项目旨在搭建一个简单的Spring MVC框架,了解Spring MVC的基础配置等内容. 一.项目结构 本项目使用idea intellij ...

  4. 造轮子:实现一个简易的 Spring IoC 容器

    作者:DeppWang.原文地址 我通过实现一个简易的 Spring IoC 容器,算是入门了 Spring 框架.本文是对实现过程的一个总结提炼,需要配合源码阅读,源码地址. 结合本文和源码,你应该 ...

  5. Spring MVC框架下的第一个Hello World程序

    本程序是一个maven程序,使用maven方便管理jar包和程序,简化了操作步骤.本程序的目的是通过一个简单的程序,了解Spring MVC框架的基本工作流程,由简入繁的学习Spring MVC框架, ...

  6. Spring学习(二)——使用Gradle构建一个简单的Spring MVC Web应用程序

    1.新建一个Gradle工程(Project) 在新建工程窗口的左侧中选择 [Gradle],右侧保持默认选择,点击next,模块命名为VelocityDemo. 2.在该工程下新建一个 module ...

  7. 手写Spring MVC框架(一) 实现简易版mvc框架

    前言 前面几篇文章中,我们讲解了Spring MVC执⾏的⼤致原理及关键组件的源码解析,今天,我们来模仿它⼿写⾃⼰的mvc框架. 先梳理一下需要实现的功能点: tomcat加载配置文件web.xml: ...

  8. Summer——从头开始写一个简易的Spring框架

    Summer--从头开始写一个简易的Spring框架                ​ 参考Spring框架实现一个简易类似的Java框架.计划陆续实现IOC.AOP.以及数据访问模块和事务控制模块. ...

  9. 使用EF Code First搭建一个简易ASP.NET MVC网站,允许数据库迁移

    本篇使用EF Code First搭建一个简易ASP.NET MVC 4网站,并允许数据库迁移. 创建一个ASP.NET MVC 4 网站. 在Models文件夹内创建Person类. public ...

随机推荐

  1. mysql自增主键

    MariaDB [test]> create table test1(id int primary key auto_increment,name varchar(20))auto_increm ...

  2. sofa graphql 2 rest api 试用

      大部分代码还是来自sofa 的官方文档,同时添加了docker && docker-compose集成 备注: 代码使用typescript 同时运行的时候为了方便直接运行使用ts ...

  3. 程序设计实践 (Brian W. Kernighan Rob Pike 著)

    第1章 风格 1.1 名字 1.2 表达式和语句 1.3 一致性和习惯用法 1.4 函数宏 1.5 神秘的数 1.6 注释 1.7 为何如此费心 第2章 算法与数据结构 2.1 检索 2.2 排序 2 ...

  4. laya的UI编辑器

    //加载一个图集 Laya.loader.load("res/atlas/comp.json",Handler.create(this,this.onLoaderComp), Ha ...

  5. HI3518E平台ISP调试环境搭建

    海思的SDK提供了ISP调试的相关工具,降低了IPC的ISP调试的难度.初次搭建ISP调试环境,记录一下. SDK版本:Hi3518_MPP_V1.0.A.0 硬件平台:HI3518E_OV9732 ...

  6. STM32的ISP下载程序方式:

    STM32的板子的串口ISP下载方法:Boot0接到3.3V上,Boot1接到GND,对板子重新上电,STM32单片机重启的时候,会进入到ISP模式.

  7. adb command

  8. jQuery实现跨域请求

    我们都知道,xhr(XMLHttpRequest)是不允许跨域的.而jQuery的ajax方法是基于xhr的,所以,直接使用它也是无法跨域的.一般的,我们是如下使用$.ajax方法的: $.ajax( ...

  9. [转]AJAX 简介

    AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. 您应当具备的基础知识 在继续学习之前,您需要对下面的知识有基本的了解: HTML / XHTML CSS JavaScript ...

  10. 【Spark Java API】broadcast、accumulator

    转载自:http://www.jianshu.com/p/082ef79c63c1 broadcast 官方文档描述: Broadcast a read-only variable to the cl ...