武俠小說練功講究打通任督二脈。程式設計練到一定程度也講究打通任督二脈。好奇心強的同學可以搜搜“打通任督二脈有什麼感覺”。 spring的任督二脈ApplicationContext 最經典的任督二脈莫過於java中spring中的ApplicationContext。用慣spring的都會覺得,這裡 ...
武俠小說練功講究打通任督二脈。程式設計練到一定程度也講究打通任督二脈。好奇心強的同學可以搜搜“打通任督二脈有什麼感覺”。
spring的任督二脈ApplicationContext
最經典的任督二脈莫過於java中spring中的ApplicationContext。用慣spring的都會覺得,這裡是這個各種實例的起源。概念解釋就不搬磚了,見官網 http://spring.io/understanding/application-context
於是乎,以前創建個jdbc需要 Class.forname() 一大堆反射出工廠類再 getConn() 得到個連接,現在只需要 context.getBean("配置名") 就能得到,還能有datasource各種實現以及高級的事務封裝。而實際使用時更方便只需要個 @Autowired 。spring興起之時大家都是在熱議其實現了IoC控制反轉原則,現在看來不僅如此,更重要的是,構造了整個bean管理體系BeanFactory,並用ApplicationContext打通了應用的任督二脈。
曾見過一個稍微複雜的應用,Oracle一主一從一物理從,可是稍微用起來就資料庫連接數不足。排查原因竟是ApplicationContext新建了三處,也就是說相應的連接池創建了三個。這裡延伸出另一個概念,叫容器。官方的說法是,BeanFactory就是一個容器,ApplicationContext則是前者的擴展,也是個容器。在這個容器里,任督二脈是打通的,bean是創建好的、管理好的、相應依賴關係是清晰的。但現在的應用伺服器多種多樣,比如spring容器、spring boot容器、tomcat容器、dubbo容器,想清楚它們之間是否打通,可以避免一些很幽靈的坑。
scoping和lifecycle-作用範圍和生命周期
應用1能不能通過ApplicationContext訪問到應用2的類或對象?正常情況下不可以,這就是作用範圍。而生命周期,則是指對象什麼時候創建什麼時候銷毀什麼時候變換狀態。
對這兩個概念更好的理解是資料庫事務。比如某用戶賬上有10元,操作1給他存入20元還沒提交,操作2查詢他當前賬戶餘額,若兩個操作在同個事務則查到結果為30元,若兩個操作是不同事務則查到結果為10元,事務隔開了兩者的作用範圍。而操作1什麼時候生效則是生命周期:開啟事務-更新餘額-提交資料庫-成功關閉或失敗回滾。
復盤業務場景的任督二脈
這裡的場景是商品-訂單-調度任務的打通。首先訂單分彙總order和商品項detail,detail記錄商品快照和批次也是很常識的。然後detail觸發個調度任務job去執行。
然而job開始結束成功失敗都應該回來通知訂單啊。job-detail有關聯,沒毛病。
然後需求變更了,有的job是單個detail,有的job是若幹detail。依然可以detail指向job,沒毛病。
又需求變更了,完成一個detail會有若幹個job。。。第一反應當然是多對多。可是要按訂單列出哪批detail做完了,order-detail-job並group by job未免太繞,於是建了一層訂單拆分detailGroup。然而,真實的需求是,商品按貨架歸集,貨架1的是若幹個detail一起做,貨架2的是單個detail,又引入一層實體為detailByShelf。
場景是:對於貨架1,detailByShelf近似於detailGroup。對於貨架2,detailByShelf用於呈現,按貨架列出詳情;detailGroup僅有單個detail且用於job。
job要回來更新訂單狀態,通過detailGroup即可。查詢要按貨架列出,則查詢detailByShelf即可。用detailGroup把job和detail串起來放進job execution context,任督二脈算是打通了。
然而需求並沒有就這樣停止。job會拆解成多個step,某些step會更新對應的detail。也就是說,step要和detail掛鉤。然而特定的step是要更新整個detailGroup的狀態的。。。
所以,更精細的設計是:step-step context根據不同類型掛鉤不同的訂單項-detail或detailGroup。而狀態更新通知是:
step狀態彙總到job
step狀態更新到detailGroup或detail,都彙總到detailGroup
detail彙總到detailByShelf再彙總到order
如何驗證這個任督二脈是否完整打通了呢?可以套三個場景。
1.step的狀態(比job更精細)能更新到detail的所有層級。
2.某一步step正在執行,可以追蹤到整個訂單以及其中的哪一項,比如 step - detail/detailGroup - order。
3.按貨架列出可以找到當前正在執行的是那一步以後,比如detailByShelf-detail-step-job
再者,哪些job是服務於同個detailGroup,也要能串起來。
所以,整個完整的打通是:
job-detailGroup,若幹個調度任務來完成一批商品
step-detail和step-detailGroup,一個步驟操作對應的整批或這批中的一個商品項
至此,整個任督二脈算是打通了,任務可以找到對應訂單或商品,訂單商品可以找到對應任務和步驟。
整個場景非常混淆的兩個點是:
1.detailByShelf只是查詢場景要用,不能混入context。因為對於貨架2,一個job只做一個detail項,detailByShelf根本不能表達相應的關係。
2.step什麼時候關聯detailGroup?不是整批或單個商品項的區別,而是這個step本身的不同。
如果問我,程式打通任督二脈是什麼感覺?我會回答,應該是,程式中想要的關聯信息都能取到,資料庫中想要的信息用幾個簡單查詢就能撈出來 的感覺吧。