本次 Cicada 已经更新到了
v1.0.3
。java
主要是解决了两个 issue,#9(Boss线程数好像设置有误 ) #8(怎么返回纯字符串内容不要JSON格式?)。git
因此本次的主要更新为:github
context
。其中我以为最核心也最有用的就是这个 Context
,并为此重构了大部分代码。json
在起初 Cicada
默认只能响应 json
,这一点确实不够灵活。加上后续也打算支持模板解析,因此不如直接在 API 中加入可以让用户自行选择不一样的响应方式。cookie
所以调整后的 API 以下。app
想要输出
text/plain
时。ide
@CicadaAction("textAction") public class TextAction implements WorkAction { @Override public void execute(CicadaContext context, Param param) throws Exception { String url = context.request().getUrl(); String method = context.request().getMethod(); context.text("hello world url=" + url + " method=" + method); } }
而响应输出
application/json
时只须要把须要响应的对象写入到json()
方法中.函数
所以原有的业务 action 中也加入了一个上下文的参数:post
/** * abstract execute method * @param context current context * @param param request params * @throws Exception throw exception */ void execute(CicadaContext context ,Param param) throws Exception;
下面就来看看这个 Context
是如何完成的。url
先看看有了这个上下文以后能够作什么。
好比有些场景下咱们须要拿到本次请求中的头信息,这时就能够经过这个 Context
对象直接获取。
固然不止是头信息:
cookie
。URL
。method
(get/post)等。其实经过这些特色能够看出这些信息其实都和一次 请求、响应
密切相关,而且各个请求之间的信息应互不影响。
这样的特性是否是很是熟悉,没错那就是 ThreadLocal
,它能够将每一个线程的信息存储起来互不影响。
ThreadLocal 的原理本次不作过多分析,只谈它在 Cicada 中的应用。
先来看看 CicadaContext
这个类的主要成员变量以及方法。
成员变量是两个接口 CicadaRequest、CicadaResponse
,名称就能看出确定是存放请求和响应数据的。
想要存放本次请求的上下文天然是在真正请求分发的地方 HttpDispatcher
。
这里改的较大的就是两个红框处,第一部分是作上下文初始化及赋值。
第二部分天然就是卸载上下文。
先看初始化。
CicadaRequest cicadaRequest = CicadaHttpRequest.init(defaultHttpRequest) ;
首先是将 request 初始化:
CicadaHttpRequest
天然是实现了 CicadaRequest
接口:
这里只保存了请求的 URL、method 等信息,后续要加的请求头也存放在此处便可。
Response
也是同理的。
这两个具体的实现类都私有化了构造函数,防止外部破坏了总体性。
接着将当前请求的上下文保存到了 CicadaContext
中。
CicadaContext.setContext(new CicadaContext(cicadaRequest,cicadaResponse));
而这个函数本质使用的则是 ThreadLocal
来存放 CicadaContext
。
public static void setContext(CicadaContext context){ ThreadLocalHolder.setCicadaContext(context) ; } private static final ThreadLocal<CicadaContext> CICADA_CONTEXT= new ThreadLocal() ; /** * set cicada context * @param context current context */ public static void setCicadaContext(CicadaContext context){ CICADA_CONTEXT.set(context) ; }
接着就是处理业务,调用不一样的 API 作不一样响应。
拿 context.text()
来讲:
其实就是设置了对应的响应方式、以及把响应内容写入了 CicadaResponse
的 httpContent
中。
业务处理完后调用 responseContent()
进行响应:
responseContent(ctx,CicadaContext.getResponse().getHttpContent());
其实就是在上下文中拿到的响应方式及响应内容返回给客户端。
最后有点很是重要,那就是 卸载上下文。
若是这里不作处理,以后随着请求的增多,ThreadLocal
里存放的数据也愈来愈多,最终确定会致使内存溢出。
因此 CicadaContext.removeContext()
就是为了及时删除当前上下文。
最后还新增了一个停机的方法。
其实也就是利用 Hook
函数实现的。
因为目前 Cicada
开的线程,占用的资源都不是特别多,因此只是关闭了 Netty 所使用的线程。
若是后续新增了自身的线程等资源,那也能够所有放到这里来进行释放。
Cicada
已经更新了 4 个版本,雏形都有了。
后续会重点实现模板解析和注解请求路由完成,把 MVC
中的 view
完成就差很少了。
尚未了解的朋友能够点击下面连接进入主页了解下。
https://github.com/TogetherOS/cicada