很多時候,為什么感覺一本書很難啃,倆字,抽象,所謂的抽象,不過是自己對這些概念不甚理解,本來程序 軟件設計的東西就是從現實里抽取的,大不了我們還原到里面就是。
在這里,我拿去飯店吃飯做比,當http這個客人受到前台的接待,前台會根據你的請求將房間號的包間給你,你過去,這個包間就是一個servlet,然后通過菜單點菜,菜單就是servlet里方法的注解,映射了每道菜制作的過程,無須對展示層展示,只需要客人看到最終的菜餚即可,這樣也就達到了隔離安全的效果,餐桌就是一個模板,每個不同的請求返回的結果可以在這個模板里集中展示,modelandview與view解析器也派上用場了。
再仔細的分解這個過程,當http受接待的時候,會受到這個飯店的配置限制吧,也就是你的web.xml就要設置為此飯店,也就是容器了,當你進入飯店的時候,攔截處理,往往會確認一下你是否預定等一些事宜,這里拿Struts2的dispatcher來說明,通過對這些請求進行預處理,這里是PrepareOperations的對象來處理的,其實其也就是個代理對象,正兒八經實現的還是dispatcher本身,由其進行轉發處理,這里就別貼源碼了,可以自己打開ide自己追着看,想想前台服務員是不是可以各種換,然后其執行的任務是不是始終都一樣,通過對客人提供的信息進行處理封裝,就像房間號和你放在一個Map中一樣,同樣,也可以在這里看到Struts和XWork融合的地方,就是dispatcher的serviceAction方法可以看到這里是是Dispatcher對象的核心邏輯調度方法,起到了中轉站的作用

* @since 2.3.17 */ public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException { Map<String, Object> extraContext = createContextMap(request, response, mapping); // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); boolean nullStack = stack == null; if (nullStack) { ActionContext ctx = ActionContext.getContext(); if (ctx != null) { stack = ctx.getValueStack(); } } if (stack != null) { extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack)); } String timerKey = "Handling request from Dispatcher"; try { UtilTimerStack.push(timerKey); String namespace = mapping.getNamespace(); String name = mapping.getName(); String method = mapping.getMethod(); ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy( namespace, name, method, extraContext, true, false); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack()); // if the ActionMapping says to go straight to a result, do it! if (mapping.getResult() != null) { Result result = mapping.getResult(); result.execute(proxy.getInvocation()); } else { proxy.execute(); } // If there was a previous value stack then set it back onto the request if (!nullStack) { request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); } } catch (ConfigurationException e) { logConfigurationException(request, e); sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e); } catch (Exception e) { if (handleException || devMode) { sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } else { throw new ServletException(e); } } finally { UtilTimerStack.pop(timerKey); } }
同樣,我們也會看到里面有幾個cleanup的方法,在客人吃完飯,需要清理殘局的時候,又要麻煩dispatcher這個調度器了,拿到框架里就是對這個事件的生命周期里框架元素的清理(總會有不少殘余的存在)。
同樣,對於我們這撥人去飯店吃飯這個流程,中間所設計的各個小事件,比如點菜,一些突發事件的特別服務等會在大伙入門登記的那一刻起已經綁在一條線程上了,對於框架里 也就是ThreadLocal,當我們付完款離開的時候,那個賬單也就沒多大用了,留個日志就可以撇過一邊了,程序里就是銷毀。
再分析,當我們點菜之后,菜單交給服務員,服務員交給后廚,后廚做完飯菜給服務員,服務員上菜,其實這里面就涉及了一個責任鏈的模式,關於菜單,還涉及到一個模式,就是構造模式,飯店根據季節和自己的優勢來設計菜單,然后由廚子來實現,而客人呢只需要點菜就可以了。
當我們消費多少之后,往往飯店會打折或者送東西,這就是涉及到了一個策略的模式,一個接口下有不同的策略實現,減100還是更大力度等等
有時候我們會遇到很奇葩的事情,就是一個菜品,就比如一盤黃瓜,往往會有一個特別高大上的名字,然后一個名字就把這盤黃瓜的身價給提升了,看看裝飾模式是多么值錢。。。
看到了吧,一個菜單都有這么多的學問,在這里這個層面的注解包含房間號 菜名,類注解假如寫房間號,方法只寫菜名就成,否則每道菜都得加房間號,具體就按照自己的想法來就成
可見一個框架的實現其實也就那些東西,各種離不開ThreadLocal模式 裝飾模式 策略模式 構造模式 責任鏈模式 調度器等,源碼來源於生活,讀源碼的時候多多聯系實際,理解好了,敲嘛,也就那回事兒了
下一篇,就總結下注解就成