码迷,mamicode.com
首页 > 编程语言 > 详细

springMvc框架实现

时间:2018-07-27 15:32:21      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:tostring   工作   创建   sse   context   load   生成   stack   集合   

一 springMvc核心功能

springMvc是基于分层MVC设计模式的spring实现,他的核心功能是:

1 url跳转

2 ioc

3 aop(本次暂不实现)

 

二spring工作流程图

技术分享图片

 

三 接下来,让我们写代码实现springMvc框架

通过注解方式实现了跳转和ioc两个核心功能,工程结构如下:

技术分享图片

分别创建注解@Controller

package com.hongsen.annotation;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
    String value();
}

 创建@RequestMapping注解

package com.hongsen.annotation;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
    String value();
}

 创建@resource注解

package com.hongsen.annotation;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
    String value();
}

 创建@Service注解

package com.hongsen.annotation;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
    String value();
}

 

创建servlet,代码如下:

package com.hongsen.servlet;

/**
 * springMvc 作用
 * <p>
 * 1 跳转
 * 2 ioc
 * 3 aop
 *
 * @author wanghongsen 2018.07.27
 */

public class DispatcherServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private List<String> classList = new ArrayList<>();
    private Map<String, Object> beanInstanceMap = new HashMap<>();
    private Map<String, Method> urlHandlerMap = new HashMap<>();

    /**
     * servlet初始化方法
     * 1 scan扫描包路径
     * 2 构造所有类集合 (list<String>)
     * 3 构造所有bean实例集合 (beanName-> bean)
     * 4 构造所有请求handler跳转(uri -> method)
     */
    public void init() throws ServletException {
        System.out.println("init() start");
        String scanBasePath = "com.hongsen";
        scan(scanBasePath);
        initBeanInstance();
        ioc();
        initUrlHandlerMap();
    }

    private void scan(String scanBasePath) {
        URL url = this.getClass().getResource("/" + scanBasePath.replace(".", "/"));
        String baseFilePath = url.getFile();
        File baseFile = new File(baseFilePath);
        String[] subFilePaths = baseFile.list();
        for (String subFilePath : subFilePaths != null ? subFilePaths : new String[0]) {
            File subFile = new File(baseFilePath + subFilePath);
            if (subFile.isDirectory()) {
                scan(scanBasePath + "." + subFilePath);
            } else {
                classList.add(scanBasePath + "." + subFilePath);
            }
        }
    }
private void initBeanInstance() { for (String beanName : classList) { try { beanName = beanName.replace(".class", ""); Class beanClass = Class.forName(beanName); try { if (beanClass.isAnnotationPresent(Controller.class)) { Controller controller = (Controller) beanClass.getAnnotation(Controller.class); beanInstanceMap.put(controller.value(), beanClass.newInstance()); } else if (beanClass.isAnnotationPresent(Service.class)) { Service service = (Service) beanClass.getAnnotation(Service.class); beanInstanceMap.put(service.value(), beanClass.newInstance()); } } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void ioc() { for (String beanName : classList) { try { beanName = beanName.replace(".class", ""); Class beanClass = Class.forName(beanName); Field[] fields = beanClass.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Resource.class)) { Resource resource = field.getAnnotation(Resource.class); String val = resource.value(); try { field.setAccessible(true); Service service = (Service) beanClass.getAnnotation(Service.class); if (service != null) { field.set(beanInstanceMap.get(service.value()), beanInstanceMap.get(val)); } else { Controller controller = (Controller) beanClass.getAnnotation(Controller.class); if (controller != null) { field.set(beanInstanceMap.get(controller.value()), beanInstanceMap.get(val)); } } } catch (IllegalAccessException e) { e.printStackTrace(); } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } private void initUrlHandlerMap() { for (String beanName : classList) { try { beanName = beanName.replace(".class", ""); Class beanClass = Class.forName(beanName); if (beanClass.isAnnotationPresent(RequestMapping.class)) { RequestMapping baseReqMap = (RequestMapping) beanClass.getAnnotation(RequestMapping.class); if (baseReqMap != null) { String requestBaseUrl = baseReqMap.value(); Method[] methods = beanClass.getMethods(); for (Method method : methods) { RequestMapping reqMap = method.getAnnotation(RequestMapping.class); if (reqMap != null) { urlHandlerMap.put(requestBaseUrl + reqMap.value(), method); } } } } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { doGet(request, response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { String uri = request.getRequestURI(); String contextPath = request.getContextPath(); String requestUrl = uri.replace(contextPath, ""); Method method = urlHandlerMap.get(requestUrl); if (method == null) { return; } Class beanClass = method.getDeclaringClass(); Controller controller = (Controller) beanClass.getAnnotation(Controller.class); Object bean = beanInstanceMap.get(controller.value()); try { Map<String, String[]> requestParameterMap = request.getParameterMap(); Object[] args = new Object[requestParameterMap.entrySet().size()]; int index = 0; for (Map.Entry entry : requestParameterMap.entrySet()) { args[index] = entry.getValue(); index++; } method.invoke(bean, args); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }

 

创建完servlet后web.xml自动生成相应代码

<load-on-startup>加这个标签,tomcat启动时会自动加载指定的servlet  大于等于0时启动tomcat会加载 servlet的init()方法 数字越小代表加载的优先级越高

<url-pattern>/这个标签是tomcat请求扫描路径,扫到后会调用servlet相应的doGet或doPost方法

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>com.hongsen.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

创建Controller类

package com.hongsen.controller;

@Controller("testController")
@RequestMapping("/test")
public class TestController {

    @Resource("testAddService")
    private TestAddServiceImpl testAddService;

    @Resource("testDelService")
    private TestDelServiceImpl testDelService;

    @RequestMapping("/add.json")
    public void testAdd() {
        testAddService.add();
    }
    @RequestMapping("/del.json")
    public void testDel(Object num1, Object num2) {
        testDelService.del(num1.toString(), num2.toString());
    }
}

 创建service接口和实现类

package com.hongsen.service;

public interface TestAddService {
    void add(String num);
}

 

package com.hongsen.service;

@Service("testAddService")
public class TestAddServiceImpl implements TestAddService{
    @Override
    public void add(String num) {
        System.out.println("add方法执行!");
    }
}

 

部署tomcat启动成功后:

访问:http://localhost:8080/test/add.json

技术分享图片

springMvc框架实现

标签:tostring   工作   创建   sse   context   load   生成   stack   集合   

原文地址:https://www.cnblogs.com/wanghongsen/p/9377651.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!