Spring Boot实践记录Java程序性能优化个人技术栈

跟我动手搭框架三之Web容器实现

2017-12-20  本文已影响13人  Chinesszz

本篇主要对Web的实现做说明,在参考文章的同事,可以把code clone下来,看,代码中有很多需要优化的地址,我已经用TODO标记处理啊,小编会不断的进行优化和分析,演示SmileBootDemo也可以git clone,debug学习

Smile源码地址

SmileBootDemo

目录

1. 核心描述类,主要保存处理方法及参数类型

其实所有方法的执行,都离不开ioc的实现,IOC主要将组件(被@SmileComponent标记过的都为组件)保存为BeanDefinition的形式,而组件中的method,主要保存为WebDefinition的形式,而method的参数名称,参数类型,参数位置索引,主要保存在ParamterDefinition,对于请求的处理,就是根据url找到对应的method,然后根据ParamterDefinition将请求参数,转换成参数原本类型,然后处理

描述类 说明 存放位置
BeanDefinition 保存组件Class字节码及实例化对象 Map<String(beanName), BeanDefinition> registeredBeans
WebDefinition 保存Url及对应的处理方法,及实例化对象,及参数类型 Map<String(url), WebDefinition> webHandlerMaps = new ConcurrentHashMap<>();
ParamterDefinition 保存参数位置索引及参数名称,参数类型,参数注解 WebDefinition.ParamterDefinition

2. Smile启动核心

3. HTTP处理实现核心

主要利用反射,将请求 URL 获取到 WebDefinition ,拿到执行方法,将请求参数,绑定到方法,作为实参,传递

Object invokeResult = method.invoke(controller, args);

并通过Netty 连接通道Channel把处理结果返回给客户端

4. 下一篇主要介绍内容

框架的实现方案属于传统的MVC机构,只不过吧视图层V取消掉了,这也是趋势,前后分离,后端只做关心数据处理,

而传统的MVC架构,核心为Servlet,SpringMVC核心为DispatchServlet,是对原始Java Servlet的一个封装,关于这点可以看小编的另一篇文章手写一个轻量级的网关API,当然使用Netty也是如此,我们的入口就是HttpDispatchServerHandler 核心方法就是messageReceivedDispatch

而只知道,这些是远远不够的,Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,我会新开二篇,专门介绍IO模型重点介绍IO multiplexing(IO多路复用)Netty如何工作 ! 包括如何实现,心跳检测

主要会介绍下面写模块

 public void messageReceivedDispatch(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        String dispatchUrl = "";
        Map<String, Object> headerMaps = new ConcurrentHashMap<>();
        if (msg instanceof HttpRequest) {
            HttpRequest req = this.request = (HttpRequest) msg;
            HttpHeaders headers = req.headers();
            headers.entries().stream().forEach(x -> {
                headerMaps.put(x.getKey(), x.getValue());
            });
            String contentType = request.headers().get("Content-Type");
            String methodName = request.getMethod().name();
            dispatchUrl = req.getUri();
            String randomUUID = UUID.randomUUID().toString().replaceAll("-", "");
            Map<String, Object> requestParams = new ConcurrentHashMap<>();
            // 处理get请求
            if (methodName.equalsIgnoreCase("GET")) {
                boolean contains = dispatchUrl.contains("?");
                if (contains){
                    String queryContent = dispatchUrl.substring(dispatchUrl.indexOf("?") + 1);
                    Map<String, Object> queryParameterFromContent = URLTools.getQueryParameterFromContent(queryContent);
                    queryParameterFromContent.entrySet().forEach(entry -> {
                        requestParams.put(entry.getKey(), entry.getValue());
                    });
                }
            }
            // 处理POST请求
            if (methodName.equalsIgnoreCase("POST")) {
                if (StringTools.endsWithIgnoreCase(contentType, "application/json")) {
                    FullHttpRequest request1 = (FullHttpRequest) msg;
                    ByteBuf jsonBuf = request1.content();
                    String jsonStr = jsonBuf.toString(CharsetUtil.UTF_8).replaceAll("\\\\s*|\\t|\\r|\\n", "");
                    if (!StringTools.isEmpty(jsonStr)) {
                        requestParams.put("BODY", jsonStr);
                    }
                } else {
                    HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
                            new DefaultHttpDataFactory(false), req);
                    List<InterfaceHttpData> postData = decoder.getBodyHttpDatas(); //
                    for (InterfaceHttpData data : postData) {
                        if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                            MemoryAttribute attribute = (MemoryAttribute) data;
                            requestParams.put(attribute.getName(), attribute.getValue());
                        }
                    }
                }
            }
            if (StringTools.contains(dispatchUrl,"?")){
                dispatchUrl = dispatchUrl.substring(0, dispatchUrl.indexOf("?"));
            }
            RequestMethod requestMethod = WebTools.getRequestMethod(methodName);
            WebDefinition webDefinition = WebContextTools.getWebDefinitionByUrl(dispatchUrl, requestMethod);
            if (webDefinition instanceof Web404Definition) {
                NettyResponse.writeResponse(ctx.channel(), "Not Found", HttpResponseStatus.NOT_FOUND);
                return;
            }
            if (webDefinition instanceof Web405Definition) {
                NettyResponse.writeResponse(ctx.channel(), "Method Not Allowed", HttpResponseStatus.METHOD_NOT_ALLOWED);
                return;
            }
            String consumes = webDefinition.getConsumes();
            if (StringTools.isNotEmpty(contentType)){
                if (StringTools.isNotEmpty(consumes)&(!contentType.equalsIgnoreCase(consumes))){
                    NettyResponse.writeResponse(ctx.channel(), "Bad Request (The content-type don't match)", HttpResponseStatus.BAD_REQUEST);
                    return;
                }
            }
            /**
             * //TODO 异步处理url获取处理的 bean
             */
            MessageRequest messageRequest = new MessageRequest(randomUUID, requestMethod, requestParams, webDefinition, headerMaps);
            MessageResponse messageResponse = new MessageResponse();
            /**
             * //TODO 根据启动配置,当如果是rpc服务就要使用MessageProcessTask
             * 如果是本地服务使用LocalMessageTask
             *
             * 此时MessageRequest和MessageResponse都是final 修饰,目的是保证始终是对当前的MessageResponse
             */
            SmileTaskChoice smileTaskChoice = new DefaultTaskProcessChoice(messageRequest, messageResponse, false);
            /**
             * //TODO 交给线程处理异步处理响应
             */
            SmileMessageExecutor.submit(smileTaskChoice.choice(), ctx, req, messageRequest, messageResponse);
        }
    }

扩展

再次声明小编也是一个菜鸟,是一只具有学习精神,并热爱编程的菜鸟, 所有的文章都是经过参考很多优秀博文,给我带来的进步,小编,希望将学习到的所有知识点,也分享给大家 ! 小编会在这里列出,参考到的优秀博文,尊重每位知识传播者的劳动果实.

如果您发现小编文章中,有错误,请及时指出,并通知小编改正,小编在此谢过.

欢迎继续关注小编~ 小编努力coding…

参考

Smart Framework 设计动力来源

segmentfault-Netty 源码分析 Netty强化学习

SpringIOC源码分析 描述类灵感来源

基于Netty打造RPC服务器设计经验谈

上一篇 下一篇

猜你喜欢

热点阅读