手写spring核心第一版

第一版没有使用设计模式,没有封装框架,只是简单的实现了IOC容器跟,DispatcherServlet处理请求

基本注解

/**
 * @author success
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    String value() default "";
}
---------------------------------------------
/**
 * @author lxz
 * @version 1.0
 * @className Controller
 * @description TODO
 * @Date 2019/9/3 10:18
 **/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
    String value() default "";
}
---------------------------------------------
/**
 * @author lxz
 * @version 1.0
 * @className RequestMapping
 * @description TODO
 * @Date 2019/9/3 10:18
 **/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
    String value() default "";
}
---------------------------------------------
/**
 * @author lxz
 * @version 1.0
 * @className RequestParam
 * @description TODO
 * @Date 2019/9/3 10:18
 **/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    String value() default "";
}
---------------------------------------------
/**
 * @author lxz
 * @version 1.0
 * @className Service
 * @description TODO
 * @Date 2019/9/3 10:18
 **/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
    String value() default "";
}

测试代码
Action(controller)

/**
 * @author lxz
 * @version 1.0
 * @className DemoAction
 * @description TODO
 * @Date 2019/9/3 10:42
 **/
@Controller
@RequestMapping("/demo")
public class DemoAction {
    @Autowired
    private DemoService demoService;

    @RequestMapping("/query")
    public void query(HttpServletRequest req, HttpServletResponse res, @RequestParam("name") String name) {
        String result = demoService.get(name);
        try {
            res.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

service

public interface DemoService {
    public String get(String name);
}
---------------------------------------------
/**
 * @author lxz
 * @version 1.0
 * @className DemoServiceImpl
 * @description TODO
 * @Date 2019/9/3 10:40
 **/
@Service
public class DemoServiceImpl implements DemoService {

    @Override
    public String get(String name) {
        return "my  name  is :" +name;
    }
}

web.xml配置

<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <servlet>
        <servlet-name>gpmvc</servlet-name>
        <servlet-class>com.apusic.mvcframework.v1.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application.properties</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>gpmvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

application.properties

scanPackage=com.apusic.demo

核心类DispatcherServlet,继承了HttpServlet,重写了init,doGet,doPost方法.
流程init()初始化时,会扫描注解,把bean添加到IOC容器
处理请求的时候调用核心方法doDispath()处理

/**
 * @author lxz
 * @version 1.0
 * @className DispatcherServlet
 * @description TODO
 * @Date 2019/9/3 10:05
 **/
public class DispatcherServlet extends HttpServlet {
    private Map<String, Object> mapping = new HashMap<String, Object>();

    @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 {
        try {
            this.doDispatch(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        String url = req.getRequestURI();
        String contextPath = req.getContextPath();
        url = url.replace(contextPath, "").replaceAll("/+", "/");
        if (!this.mapping.containsKey(url)) {
            resp.getWriter().write("404 Not Found");
            return;
        }
        Method method = (Method) this.mapping.get(url);
        Map<String, String[]> parameterMap = req.getParameterMap();
        String name = method.getDeclaringClass().getName();
        method.invoke(this.mapping.get(method.getDeclaringClass().getName()), new Object[]{req, resp, parameterMap.get(
                "name")[0]});
    }

    @Override
    public void init() throws ServletException {

        try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("application.properties")) {
            Properties ps = new Properties();
            ps.load(is);
            String scanPackage = ps.getProperty("scanPackage");
            doScanner(scanPackage);
            for (String className : mapping.keySet()) {
                if (!className.contains(".")) {
                    continue;
                }
                Class<?> clazz = Class.forName(className);
                if (clazz.isAnnotationPresent(Controller.class)) {
                    mapping.put(className, clazz.newInstance());
                    String baseUrl = "";
                    if (clazz.isAnnotationPresent(RequestMapping.class)) {
                        RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
                        baseUrl = requestMapping.value();
                    }
                    Method[] methods = clazz.getMethods();
                    for (Method method : methods) {
                        if (!method.isAnnotationPresent(RequestMapping.class)) {
                            continue;
                        }
                        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                        String url = baseUrl + requestMapping.value().replace("/+", "/");
                        mapping.put(url, method);
                        System.out.println("Mapped" + url + "," + method);
                    }
                } else if (clazz.isAnnotationPresent(Service.class)) {
                    Service service = clazz.getAnnotation(Service.class);
                    String beanName = service.value();
                    if ("".equals(beanName)) {
                        beanName = clazz.getName();
                    }
                    Object instance = clazz.newInstance();
                    mapping.put(beanName, instance);
                    for (Class<?> anInterface : clazz.getInterfaces()) {
                        mapping.put(anInterface.getName(), instance);
                    }
                } else {
                    continue;
                }
            }

            for (Object object : mapping.values()) {
                if (object == null) {
                    continue;
                }
                Class<?> clazz = object.getClass();
                if (clazz.isAnnotationPresent(Controller.class)) {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        if (!field.isAnnotationPresent(Autowired.class)) {
                            continue;
                        }
                        String beanName = field.getAnnotation(Autowired.class).value();
                        if ("".equals(beanName)) {
                            beanName = field.getType().getName();
                            field.setAccessible(true);
                            field.set(mapping.get(clazz.getName()), mapping.get(beanName));
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("mvc framework  is init");
        }

    }

    private void doScanner(String scanPackage) {
        URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));
        if (url != null) {
            File file = new File(url.getFile());

            for (File listFile : Objects.requireNonNull(file.listFiles())) {
                if (listFile.isDirectory()) {
                    doScanner(scanPackage + "." + listFile.getName());
                } else {
                    if (file.getName().endsWith(".class")) {
                        continue;
                    }
                    String className = (scanPackage + "." + listFile.getName().replace(".class", ""));
                    mapping.put(className, null);
                }
            }
        }
    }
}

在这里插入图片描述

此时spring核心原理已经写出来了.
后续更新优化版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值