SpringMVC適配器模式代碼示例
此處采用了適配器模式, 由于Controller的類型不同,有多重實(shí)現(xiàn)方式,那么調(diào)用方式就不是確定的,如果需要直接調(diào)用Controller方法,需要在代碼中寫成如下形式:
if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanceof XXX){ ... }else if(...){ ... }
這樣假設(shè)如果我們增加一個(gè)HardController,就要在代碼中加入一行 if(mappedHandler.getHandler() instanceof HardController)
這種形式就使得程序難以維護(hù),也違反了設(shè)計(jì)模式中的開閉原則 -- 對擴(kuò)展開放,對修改關(guān)閉。
因此Spring定義了一個(gè)適配接口,使得每一種Controller有一種對應(yīng)的適配器實(shí)現(xiàn)類,
讓適配器代替controller執(zhí)行相應(yīng)的方法。這樣在擴(kuò)展Controller 時(shí),只需要增加一個(gè)適配器類就完成了SpringMVC的擴(kuò)展了,真的是很精巧的做法!
廢話不多說還是上代碼吧,為了看得清楚,就自己實(shí)現(xiàn)一套代碼來模擬springMVC, 直接貼Spring源碼容易降低關(guān)注點(diǎn)。
//定義一個(gè)Adapter接口 public interface HandlerAdapter { public Boolean supports(Object handler); public void handle(Object handler); } //以下是三種Controller實(shí)現(xiàn) public interface Controller { } public class HttpController implements Controller{ public void doHttpHandler(){ System.out.println("http..."); } } public class SimpleController implements Controller{ public void doSimplerHandler(){ System.out.println("simple..."); } } public class AnnotationController implements Controller{ public void doAnnotationHandler(){ System.out.println("annotation..."); } } //下面編寫適配器類 public class SimpleHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((SimpleController)handler).doSimplerHandler(); } public Boolean supports(Object handler) { return (handler instanceof SimpleController); } } public class HttpHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((HttpController)handler).doHttpHandler(); } public Boolean supports(Object handler) { return (handler instanceof HttpController); } } public class AnnotationHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((AnnotationController)handler).doAnnotationHandler(); } public Boolean supports(Object handler) { return (handler instanceof AnnotationController); } } //模擬一個(gè)DispatcherServlet import java.util.ArrayList; import java.util.List; public class DispatchServlet { public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>(); public DispatchServlet(){ handlerAdapters.add(new AnnotationHandlerAdapter()); handlerAdapters.add(new HttpHandlerAdapter()); handlerAdapters.add(new SimpleHandlerAdapter()); } public void doDispatch(){ //此處模擬SpringMVC從request取handler的對象,僅僅new出,可以出, //不論實(shí)現(xiàn)何種Controller,適配器總能經(jīng)過適配以后得到想要的結(jié)果 // HttpController controller = new HttpController(); // AnnotationController controller = new AnnotationController(); SimpleController controller = new SimpleController(); //得到對應(yīng)適配器 HandlerAdapter adapter = getHandler(controller); //通過適配器執(zhí)行對應(yīng)的controller對應(yīng)方法 adapter.handle(controller); } public HandlerAdapter getHandler(Controller controller){ for (HandlerAdapter adapter: this.handlerAdapters){ if(adapter.supports(controller)){ return adapter; } } return null; } public static void main(String[] args){ new DispatchServlet().doDispatch(); } }
通過這個(gè)模式可以看出開源代碼中的精妙,我們在看框架源碼時(shí)需要有目標(biāo)的看,這樣會(huì)找到很多自己需要學(xué)習(xí)的東西,目前很多分析源碼的帖子大部分是講解what,how,
以此來拋磚引玉,希望各位能夠一起來討論“why”
總結(jié)
以上就是本文關(guān)于SpringMVC適配器模式代碼示例的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
相關(guān)文章
Java向List集合中批量添加元素的實(shí)現(xiàn)方法
這篇文章主要介紹了Java向List集合中批量添加元素的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05mybatis 中 foreach collection的用法小結(jié)(三種)
這篇文章主要介紹了mybatis 中 foreach collection的用法小結(jié)(三種),需要的朋友可以參考下2017-10-10使用MyBatis攔截器實(shí)現(xiàn)SQL的完整打印
當(dāng)我們使用Mybatis結(jié)合Mybatis-plus進(jìn)行開發(fā)時(shí),為了查看執(zhí)行sql的信息通常我們可以通過屬性配置的方式打印出執(zhí)行的sql語句,但這樣的打印出了sql語句常帶有占位符信息,不利于排錯(cuò),所以本文介紹了構(gòu)建MyBatis攔截器,實(shí)現(xiàn)SQL的完整打印,需要的朋友可以參考下2024-07-07在Mybatis @Select注解中實(shí)現(xiàn)拼寫動(dòng)態(tài)sql
這篇文章主要介紹了在Mybatis @Select注解中實(shí)現(xiàn)拼寫動(dòng)態(tài)sql,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11使用JPA雙向多對多關(guān)聯(lián)關(guān)系@ManyToMany
這篇文章主要介紹了使用JPA雙向多對多關(guān)聯(lián)關(guān)系@ManyToMany,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06java實(shí)現(xiàn)大數(shù)加法(BigDecimal)的實(shí)例代碼
之前寫過用vector、string實(shí)現(xiàn)大數(shù)加法,現(xiàn)在用java的BigDecimal類,代碼簡單很多。但是在online-judge上,java的代碼運(yùn)行時(shí)間和內(nèi)存大得多2013-10-10