扯淡:
看到首頁又來一個C#和java爭論,我也是蠻醉的,玩C#好的同學多得是,一個技術能全通所有技術是不可能,術業本來就是有專攻,即使能借鑒那也是比較有高度的概念借鑒而已。
而語言這種東西要分高低,我覺得是件很愚蠢的事。如果你真的想討論,建議你寫個萬字級別的文章來論述,我想這樣的話等你寫完你也一定成長了不少??傊粋€告誡,別做無益處無樂趣卻太浪費時間的事情。
我自己玩java,主要也是喜歡 開源 這兩個字。看得到更多別人想法的實現細節對于我這種個性的開發是一件蠻興奮的事情。而我想喜歡C#的同學自有自己的樂趣所在。
主題:
上一篇文章地址:請求路由到業務方法設計(1)
@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; }}
讓我們繼續前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不會成功。
新聞熱點
疑難解答