本次 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