亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

請求路由到業務方法設計(2)-我們到底能走多遠系列(45)

2019-11-14 15:10:16
字體:
來源:轉載
供稿:網友

請求路由到業務方法設計(2)

扯淡:

看到首頁又來一個C#和java爭論,我也是蠻醉的,玩C#好的同學多得是,一個技術能全通所有技術是不可能,術業本來就是有專攻,即使能借鑒那也是比較有高度的概念借鑒而已。

而語言這種東西要分高低,我覺得是件很愚蠢的事。如果你真的想討論,建議你寫個萬字級別的文章來論述,我想這樣的話等你寫完你也一定成長了不少??傊粋€告誡,別做無益處無樂趣卻太浪費時間的事情。

我自己玩java,主要也是喜歡 開源 這兩個字。看得到更多別人想法的實現細節對于我這種個性的開發是一件蠻興奮的事情。而我想喜歡C#的同學自有自己的樂趣所在。

 

主題:

上一篇文章地址:請求路由到業務方法設計(1)

希望實現的功能在上一篇文章描述過了,參考這個ROP框架,是因為它也要解決這個問題,而且是java實現,可以參考。
我這邊是自己參考后實現了一個,實際ROP框架實現參考源碼,不過git上已經很久沒有維護了。
另外:個人覺得ROP是java web開發可以詳細閱讀的小框架,花不了太多時間,了解結構,用到的模式,都是很好的學習素材,因為不是很龐大,所以可以有一個全局觀。讀大的框架,經驗不夠的時候,容易迷失,而且東西學的反而少。
 
思路是這樣:核心我們要在應用啟動后,產生出一個路由Map,這個map維護請求中的某個值對應執行哪一個類的哪個方法,也就是對應著那一段業務邏輯。如此就可以把輸入組裝好,放進統一如有接口中,然后就會執行相應邏輯。
 
這里使用注解的方式,來標識出那些業務邏輯,也就是給實現的業務邏輯打上標簽,用于啟動時組裝出路由Map。
 
第一個注解標識類:
@Target({ElementType. TYPE})@Retention(RetentionPolicy.RUNTIME )@Documented@Servicepublic @interface OpenServiceBean {}

 

第二個注解標識方法,那么這個路由map就是指定到方法的,這里可以注意到這個標簽就是method字段,那么前端傳過來的值中有這個字段:

@Target({ElementType. TYPE})@Retention(RetentionPolicy.RUNTIME )@Documentedpublic @interface OpenServiceMethod {     /**     * 服務的方法名,即由method參數指定的服務方法名     *     */    String method() default "";       /**     * 服務的中文名稱     *     */    String title() default "";}

 

接下來就是啟動的時候解析,那些寫著這些注解的類和方法了,然后緩存到map中。

 

public interface OpenServiceRouter {     // 統一入口接口     public JSON doService(JSONObject json);}

 

下面是實現類,這個類是啟動類:

// 實現,利用sPRing,實例化bean后,執行afterPropertiesSet()方法。// 而所有使用了注解的bean,都會被spring初始化好,也就是說,我們建立路由Map的時候,spring的容器已經準備好了,// 那么我們就可以去容器里拿這些bean來用了,所以此時我們必須先拿到applicationContext對象。所以使用了ApplicationContextAware。@Servicepublic class OpenServiceRouterImpl implements InitializingBean, OpenServiceRouter, ApplicationContextAware{     private Map<String, ServiceMethodHandler> routerMap;          private OpenServiceContext context;          private AbstractBaseServiceAdapter serviceAdapter;     private ApplicationContext applicationContext;          @Override     public void afterPropertiesSet() throws Exception {           // 執行器          this.serviceAdapter = new AbstractBaseServiceAdapter();          // 產生路由Map,具體看OpenServiceContext          this.context = new OpenServiceContext(applicationContext);          this.routerMap = this.context.getHandlerMap();     }     @Override     public JSON doService(JSONObject json) {          // 根據method拿出指定的handler          ServiceMethodHandler handler = routerMap.get(json.getString("method"));          if(handler == null){               return new JSONObject();//TODO                   }          // 拿到執行handler,執行          return serviceAdapter.execute(json, handler);     }     @Override     public void setApplicationContext(ApplicationContext applicationContext)               throws BeansException {          this.applicationContext = applicationContext;     }}

 

ServiceMethodHandler 用來存放處理器,也就是那些業務邏輯類和方法,那個Map的value也就是這個:

public class ServiceMethodHandler {     public Class<? extends  OpenRequest> getRequestType() {            return requestType;     }     public void setRequestType(Class<? extends  OpenRequest> requestType) {            this. requestType = requestType;     }     private Object handler;     private Method handlerMethod;     //處理方法的請求對象類    private Class<? extends  OpenRequest> requestType = OpenRequest.class;        public Object getHandler() {            return handler;     }     public void setHandler(Object handler) {            this. handler = handler;     }     public Method getHandlerMethod() {            return handlerMethod;     }     public void setHandlerMethod(Method handlerMethod) {            this. handlerMethod = handlerMethod;     }}

 

OpenServiceContext用來實際啟動時將那些注解的類全部解析成路由Map,也算核心代碼,上面提到的ROP框架也是一樣的做法,值得借鑒,以后自己想寫個小框架可以用用。

public class OpenServiceContext{     private Map<String, ServiceMethodHandler> handlerMap = new HashMap<String, ServiceMethodHandler>();     private Set<String> methodNameSet = new HashSet<String>();     private ApplicationContext applicationContext;          public OpenServiceContext(){           initContext( this. applicationContext);     }          public OpenServiceContext( final ApplicationContext context){           initContext(context);     }          public void addServiceMethodHandler(String methodName, ServiceMethodHandler serviceMethodHandler){            methodNameSet.add(methodName);            handlerMap.put(methodName, serviceMethodHandler);     }          public boolean isValidMethod(String methodName){            return methodNameSet.contains(methodName);     }          public Map<String, ServiceMethodHandler> getHandlerMap(){            return handlerMap;     }     // 執行方法前需要將ApplicationContext準備好     public void initContext( final ApplicationContext context){           String[] beanNames = context.getBeanNamesForType(Object.class );            if(beanNames == null){                 return;           }        for (final String beanName : beanNames) {            Class<?> handlerType = context.getType(beanName);            // 本方法是最后一個參數根據注解直接過濾出來的method,放入Map            ReflectionUtils. doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {                        public void doWith(Method method) throws IllegalArgumentException, IllegalaccessException {                            ReflectionUtils.makeAccessible(method);                            OpenServiceMethod serviceMethod = method.getAnnotation(OpenServiceMethod .class);                            ServiceMethodHandler serviceMethodHandler = new ServiceMethodHandler();                            //1.set handler                            serviceMethodHandler.setHandler(context.getBean(beanName)); //handler                            serviceMethodHandler.setHandlerMethod(method); //handler'method                            if(!ClassUtils. isAssignable(OpenResponse.class, method.getReturnType())){                                throw new OpenServiceException(method.getDeclaringClass().getName() + "." + method.getName()                                                       + "的返回參數必須是" + OpenResponse.class.getName());                            }                            if (method.getParameterTypes().length > 1) {//handler method's parameter                                throw new OpenServiceException(method.getDeclaringClass().getName() + "." + method.getName()                                        + "的入參只能是" + OpenRequest.class.getName() + "或無入參。" );                            } else if (method.getParameterTypes().length == 1) {                                Class<?> paramType = method.getParameterTypes()[0];                                if (!ClassUtils.isAssignable(OpenRequest. class, paramType)) {                                    throw new OpenServiceException(method.getDeclaringClass().getName() + "." + method.getName()                                            + "的入參必須是" + OpenRequest.class.getName());                                }                                serviceMethodHandler.setRequestType((Class<? extends OpenRequest>)paramType);                            } else {                                 throw new OpenServiceException(method.getDeclaringClass().getName() + "." + method.getName() + "無入參" );                            }                            addServiceMethodHandler(serviceMethod.method(), serviceMethodHandler);                        }                    },                    new ReflectionUtils.MethodFilter() {                                                                 @Override                                 public boolean matches(Method method) {                                      return AnnotationUtils.findAnnotation(method, OpenServiceMethod. class) != null;                                }                           }            );        }     }     }

 

接下來就是執行器來執行指定邏輯代碼了,因為Map中放的是Method,執行需要進行反射:

public class AbstractBaseServiceAdapter {     /**      * json ==> OpenRequest      * @param json      * @param handler      * @return      */     public final OpenRequest decode(JSON json, ServiceMethodHandler handler){           Class<? extends  OpenRequest> requestClass = handler.getRequestType();           ObjectMapper mapper = new ObjectMapper();            OpenRequest request = null;            try {                request = mapper.readValue(json.toJSONString(), requestClass);           } catch (Exception e) {                 throw new OpenServiceException( "open decode had a exp json==>"+json , e);           }                       return request;                }     /**      * OpenResponse ==> json      * @param response      * @return      */     public final JSON encode(OpenResponse response){           ObjectMapper mapper = new ObjectMapper();                // Convert object to JSON string            JSON json = null;        try {                String j =  mapper.writeValueAsString(response);                json = JSON. parSEObject(j);           } catch (Exception e) {                 throw new OpenServiceException( "open encode had a exp response==>"+response.getClass() , e);           }            return json;     }               public final JSON execute(JSON json, ServiceMethodHandler handler) {            OpenRequest request = this.decode(json, handler);                      handler.getHandler();           handler.getHandlerMethod();                      OpenResponse response = null;                   try {               // 執行器執行對應方法                response = (OpenResponse) handler.getHandlerMethod().invoke(                           handler.getHandler(), request);           } catch (Exception e) {                 throw new OpenServiceException( "open invoke had a exp json"+json , e);           }           JSON retrunJson = this.encode(response);            return retrunJson;     }}

 

至此結構代碼已經理清,具體還有method的輸入輸出,需要統一接口實現,以保證執行器代碼的統一。
 
總結:
 
1,這個方案的核心就是利用注解來組裝好這個路由Map,以及用反射的方式執行對應的方法。
2,另外Spring的確十分強大,很多封裝代碼可以被使用。學習java的應該深入進去挖寶。
 
 
 

讓我們繼續前行

----------------------------------------------------------------------

努力不一定成功,但不努力肯定不會成功。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美极品欧美精品欧美视频| 欧美激情亚洲自拍| 精品福利视频导航| 久久久噜久噜久久综合| 日韩经典第一页| 在线精品国产成人综合| 成人福利在线视频| 成人免费视频a| 国产精品久久综合av爱欲tv| 欧美性猛交xxxx乱大交极品| 久久久精品久久久久| 国产日韩欧美91| 精品久久久久久久大神国产| 亚洲激情视频在线观看| 狠狠爱在线视频一区| 亚洲国产成人爱av在线播放| www.日韩av.com| 欧美精品一区在线播放| 色香阁99久久精品久久久| 97香蕉超级碰碰久久免费的优势| 国产69精品久久久| 亚洲福利视频在线| 欧美精品久久久久久久免费观看| 国产精品旅馆在线| 成人黄色午夜影院| 激情成人在线视频| 成人久久一区二区| 亚洲高清福利视频| 欧美一级bbbbb性bbbb喷潮片| 日韩在线一区二区三区免费视频| 日韩美女激情视频| 国产精品成人播放| 成人啪啪免费看| 九九精品在线观看| 成人精品一区二区三区电影黑人| 国产成人综合久久| 欧美在线观看一区二区三区| 国产精品久久久久久久电影| 国产在线观看精品一区二区三区| 久久久午夜视频| 欧美激情videos| 在线播放国产一区中文字幕剧情欧美| 欧美理论电影在线播放| 国产精自产拍久久久久久| 97视频国产在线| 久久久久久久久久久免费| 久久国产精品久久久久久| 亚洲欧洲在线免费| 尤物99国产成人精品视频| 日韩欧美第一页| 国产午夜精品久久久| 午夜伦理精品一区| 深夜成人在线观看| 国产精品视频久久| 色综合久久精品亚洲国产| 中文字幕亚洲激情| 欧美性猛交xxxx免费看久久久| 亚洲精品国产欧美| 国产精品精品一区二区三区午夜版| 青草青草久热精品视频在线观看| 国产综合在线观看视频| 日韩免费不卡av| 日韩中文娱乐网| 国产视频在线观看一区二区| 2019亚洲男人天堂| 亚洲一区二区三区香蕉| 中文一区二区视频| 欧美激情第99页| 国产精品人成电影| 久久久91精品国产| 亚洲影院色无极综合| 欧美精品在线观看91| 日本最新高清不卡中文字幕| 色婷婷综合久久久久中文字幕1| 欧美日韩一区二区在线| 亚洲男人7777| 成人黄色在线播放| 色噜噜国产精品视频一区二区| 91精品国产成人www| 亚洲国产高清福利视频| 欧美性猛交xxx| 欧美中文在线视频| 欧美野外猛男的大粗鳮| 奇米成人av国产一区二区三区| 日韩欧美极品在线观看| 欧美日韩免费网站| 欧美午夜视频在线观看| 91精品国产网站| 国产精品香蕉av| 久久综合伊人77777尤物| 主播福利视频一区| 亚洲第一精品电影| 久久久久女教师免费一区| 国产一区二区三区在线观看网站| 国产精品吹潮在线观看| 国语自产精品视频在线看一大j8| 久久久久久久97| 亚洲视频第一页| 精品日本高清在线播放| 欧美亚洲在线视频| 一区二区中文字幕| 97高清免费视频| 欧美一乱一性一交一视频| 国产91免费看片| 欧美精品在线看| 国产日韩欧美在线视频观看| 91精品国产91久久久久| 日本一区二区三区四区视频| 久久久精品久久久久| 91国自产精品中文字幕亚洲| 国产精欧美一区二区三区| 国产原创欧美精品| 岛国av一区二区三区| 另类天堂视频在线观看| 国产欧美一区二区三区视频| 26uuu另类亚洲欧美日本一| 日韩精品亚洲元码| 国产精品91久久| 久久在线视频在线| 国产乱肥老妇国产一区二| 日韩av在线一区二区| 亚洲伊人成综合成人网| 午夜精品三级视频福利| www日韩中文字幕在线看| 精品日本美女福利在线观看| 国产一区二区欧美日韩| 亚洲国产成人av在线| 色偷偷偷亚洲综合网另类| 亚洲欧洲视频在线| 欧美综合第一页| 久久久女人电视剧免费播放下载| 成人h片在线播放免费网站| 欧美亚洲激情视频| 欧美日韩亚洲高清| 夜夜嗨av一区二区三区四区| 久久国产精品免费视频| 992tv成人免费视频| 久久久精品久久| 国产精品久久久久久久久久99| 亚洲欧洲一区二区三区在线观看| 精品成人69xx.xyz| 57pao国产精品一区| 97视频色精品| 北条麻妃一区二区三区中文字幕| 亚洲精品国产福利| 色老头一区二区三区| 国产精品久久久久久久久久久久久久| 欧美裸体xxxxx| 国产91在线视频| 欧美性理论片在线观看片免费| 欧美极品少妇xxxxⅹ裸体艺术| 亚洲国产成人在线播放| 欧美日韩精品在线观看| 中文欧美在线视频| 亚洲欧美日本另类| 国产精品视频地址| 亚洲一区二区三区在线免费观看| 欧美中文字幕在线观看| 亚洲深夜福利在线| 国产精品香蕉在线观看| 成人福利视频在线观看| 国产精品美女主播| 51精品在线观看| 国产精品免费视频久久久|