乐趣区

从零开始实现mvc框架

造个轮子— 从 socket 到 mvc 框架

1. 缘起

为什么要造这个轮子?现在 Java 领域的 mvc 框架层出不穷,springmvc,struts2,jfinal;容器方面有 tomcat,jetty,undertow。为什么要造这个不成熟的东西出来?我想起我在大二刚接触 java web 是学的 struts2,一大堆 xml 配置让我看到吐,感觉这掩盖了网络编程的本来面目,为什么不从底层的 socket 写起,解析 http 协议,封装请求和响应,我觉得这样更能理解本质。于是我造了第一个轮子作为这个想法的验证 MineServer, 这个轮子现在放在 github 上,但这只是一个玩具项目,我想造的是一个完整的轮子,于是我开了这个坑 Boomvc。

2. 我想要什么?

我想要一个类似 spring boot 这种开发体验的 web 框架,可以用一行代码开启一个 http server,没有 xml 配置,使用注解和简单的 properties 配置文件,最简的依赖,可以不用遵守 servlet 规范的 web mvc 框架。框架要包括 3 个部分:底层的 http server 和上层的 mvc 框架, 以及 ioc 容器。http server 可以自己从 socket 实现,也可以使用 netty 这样的网络框架实现。

3. 实现

目前框架已经基本实现完成,还有很多 bug,但是完成了自己的想法,我感到很开心。目前框架实现了一下的功能。

  1. 轻量级 MVC 框架,不依赖任何 web 容器
  2. 可以直接运行 jar 包启动一个 web 服务
  3. 支持 cookie
  4. 支持 session
  5. 使用 jdk 原生的 nio api 实现 http server
  6. Restful 风格路由
  7. 支持模板引擎
  8. 支持 JSON 输出

可以像 spring boot 那样一行代码启动 :)

public static void main(String[] args) {Boom.me().start(Main.class, args);
}

写一个 controller

@RestPath
public class TestController {@GetRoute("/")
    public String hello(){return "hello world";}
}

同时还有过滤器和拦截器

public interface Filter {void init(FilterConfig config);

    void doFilter(HttpRequest request, HttpResponse response, FilterChain chain) throws Exception;

    void destroy();}

public interface Interceptor {boolean preHandle(HttpRequest request, HttpResponse response);

    void postHandle(HttpRequest request, HttpResponse response, ModelAndView modelAndView);

    void afterCompletion(HttpRequest request, HttpResponse response, Exception e);

}

然后像 spring boot 那样注册,写一个配置类继承 WebMvcConfigurerAdapter

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter{
    @Override
    public void addInterceptors(WebMvcRegistry registry) {Interceptor interceptor = new MyInterceptor();
        registry.addInterceptor(interceptor)
                .order(1)
                .patternUrl("/*");
    }

    @Override
    public void addFilters(WebMvcRegistry registry) {Filter filter = new MyFilter();
        registry.addFilter(filter)
                .addFilterInitParameter("hello", "world")
                .addFilterInitParameter("ni", "hao")
                .addFilterPathPattern("/*")
                .order(1);
    }
}

做为一个开源的新手,我写了这个项目,有很多不足和 bug,希望有大牛可以多多指教。如果你有兴趣,欢迎 star,fork,提 issues,一起共同学习讨论 Boomvc????

退出移动版