Gaea源码阅读(三):服务端启动流程

转载地址:http://blog.csdn.net/m_vptr/article/details/9163319

相对于客户端,服务器端工作就比较多了。服务器端需要load jar包,利用fliter实现方法级的权限控制


[java]  view plain  copy
  1. // load service config  
  2. logger.info("load service config...");  
  3. ServiceConfig sc = loadServiceConfig(gaeaConfigDefaultPath, gaeaConfigPath);  
  4.   
  5. // init class loader  
  6. logger.info("-----------------loading global jars------------------");  
  7. DynamicClassLoader classLoader = new DynamicClassLoader();  
  8. classLoader.addFolder(  
  9.         rootPath + "service/deploy/" + sc.getString("gaea.service.name") + "/",  
  10.         rootPath + "service/lib/",  
  11.         rootPath + "lib"  
  12.         );  
  13.   
  14. //通过反射调用URLClassLoader的addURL方法  
  15. GlobalClassLoader.addSystemClassPathFolder(  
  16.         rootPath + "service/deploy/" + sc.getString("gaea.service.name") + "/",  
  17.         rootPath + "service/lib/",  
  18.         rootPath + "lib"  
  19.         );  
  20. logger.info("-------------------------end-------------------------\n");  
  21.   
  22. if(new File(serviceFolderPath).isDirectory() || serviceName valid) {  
  23.     // load proxy factory  
  24.     logger.info("--------------------loading proxys-------------------");  
  25.     IProxyFactory proxyFactory = ProxyFactoryLoader.loadProxyFactory(classLoader);  
  26.     Global.getSingleton().setProxyFactory(proxyFactory);  
  27.     logger.info("-------------------------end-------------------------\n");  
  28.       
  29.     // load init beans  
  30.     logger.info("-----------------loading init beans------------------");  
  31.     loadInitBeans(classLoader, sc);  
  32.     logger.info("-------------------------end-------------------------\n");  
  33. }  
  34.   
  35.   
  36. // load global request-filters  
  37. logger.info("-----------loading global request filters------------");  
  38. List<IFilter> requestFilters = loadFilters(classLoader, sc, "gaea.filter.global.request");  
  39. for(IFilter filter : requestFilters) {  
  40.     Global.getSingleton().addGlobalRequestFilter(filter);  
  41. }  
  42. logger.info("-------------------------end-------------------------\n");  
  43.   
  44. // load global response-filters  
  45. logger.info("-----------loading global response filters-----------");  
  46. List<IFilter> responseFilters = loadFilters(classLoader, sc, "gaea.filter.global.response");  
  47. for(IFilter filter : responseFilters) {  
  48.     Global.getSingleton().addGlobalResponseFilter(filter);  
  49. }  
  50. logger.info("-------------------------end-------------------------\n");  
  51.   
  52. // load connection filters  
  53. logger.info("-----------loading connection filters-----------");  
  54. List<IFilter> connFilters = loadFilters(classLoader, sc, "gaea.filter.connection");  
  55. for(IFilter filter : connFilters) {  
  56.     Global.getSingleton().addConnectionFilter(filter);  
  57. }  
  58. logger.info("-------------------------end-------------------------\n");  
  59.   
  60. // load secureKey 当gaea.secure不为true时不启动权限认证  
  61. logger.info("------------------load secureKey start---------------------");  
  62. if(sc.getString("gaea.secure") != null && "true".equalsIgnoreCase(sc.getString("gaea.secure"))) {  
  63.     logger.info("gaea.secure:" + sc.getString("gaea.secure"));  
  64.     loadSecureKey(sc,serviceFolderPath);  
  65. }  
  66. logger.info("------------------load secureKey end----------------------\n");  
  67.   
  68. // load servers  
  69. logger.info("------------------ starting servers -----------------");  
  70. loadServers(classLoader, sc);  
  71. logger.info("-------------------------end-------------------------\n");  
  72.   
  73. // add current service file to monitor  
  74. if(sc.getBoolean("gaea.hotdeploy")) {  
  75.     logger.info("------------------init file monitor-----------------");  
  76.     addFileMonitor(rootPath, sc.getString("gaea.service.name"));  
  77.     logger.info("-------------------------end-------------------------\n");  
  78. }  


//load proxy factory

[java]  view plain  copy
  1. //ProxyFactoryLoader.loadProxyFactory  
  2.         CreateManager cm = new CreateManager();  
  3.         return cm.careteProxy(Global.getSingleton().getRootPath()   
  4.                                   + "service/deploy/"   
  5.                                   + ("gaea.service.name"),   
  6.                               classLoader);  
  7.   
  8. // CreateManager.createProxy  
  9.         //ContractInfo  
  10.         if (file != null && file.exists()) {  
  11.             //如果存在Serviceframe.xml  
  12.             serviceContract = ContractConfig.loadContractInfo(configPath, classLoader);  
  13.         } else {  
  14.             //只扫描deploy/{serviceName}目录下的jar包  
  15.             serviceContract = ScanClass.getContractInfo(serviceRootPath + "/", classLoader);  
  16.         }  

    ServerContract是SessionBean的列表,SessionBean包括接口名,接口->实例Map,类信息。在Serviceframe.xml中可配置.

 

    如果存在Serviceframe.xml,则扫描Serviceframe.xml,否则直接扫描jar包。

    Serviceframe.xml的格式为:

[html]  view plain  copy
  1. <interface>  
  2.     <class></class>  
  3.     <lookup></lookup>  
  4. </interface>  

// ScanClass.getContractInfo

[java]  view plain  copy
  1. //扫描注解,分别解析contract(接口),behavior(实现)  
  2.                          ServiceBehaviorbehavior = cls.getAnnotation(ServiceBehavior.class);  
  3.                          ServiceContract contract= cls.getAnnotation(ServiceContract.class);  
  4.                          if(behavior==null && contract == null) {  
  5.                                    continue;  
  6.                          }  
  7.                            
  8.                          if(contract !=null) {  
  9.                                    ClassInfo ci = contract(cls);  
  10.                                    if(ci !=null) {  
  11.                                             contractClassInfos.add(ci);  
  12.                                    }  
  13.                          } elseif(behavior!= null) {  
  14.                                    ClassInfo ci = behavior(cls);  
  15.                                    if(ci !=null) {  
  16.                                             behaviorClassInfos.add(ci);  
  17.                                    }  
  18.                          }  


[java]  view plain  copy
  1. //ScanClass.Contract()  
  2.     //获取该类所有接口  
  3.     List<Class<?>>interfaceList = getInterfaces(cls);  
  4.     List<ClassInfo.MethodInfo>methodInfos = newArrayList<ClassInfo.MethodInfo>();  
  5.   
  6.     for(Class<?>interfaceCls : interfaceList) {  
  7.             //接口所有方法  
  8.             Method[]methods = interfaceCls.getDeclaredMethods();  
  9.             if(contractAnn!=null && contractAnn.defaultAll()){  
  10.                       for(Methodm : methods) {  
  11.                                 if(Modifier.isPublic(m.getModifiers())|| Modifier.isProtected(m.getModifiers())) {  
  12.                                          ClassInfo.MethodInfo mi =newClassInfo.MethodInfo();  
  13.                                          mi.setMethod(m);  
  14.                                          methodInfos.add(mi);  
  15.                                 }  
  16.                       }  
  17.             }else {  
  18.                       //没有@ServiceContract注解则默认扫Public并OperationContract注解了的方法  
  19.                       for(Methodm : methods) {  
  20.                                 if(Modifier.isPublic(m.getModifiers())|| Modifier.isProtected(m.getModifiers())) {  
  21.                                          OperationContract oc =m.getAnnotation(OperationContract.class);  
  22.                                          if(oc !=null) {  
  23.                                                   ClassInfo.MethodInfo mi =newClassInfo.MethodInfo();  
  24.                                                   mi.setMethod(m);  
  25.                                                   methodInfos.add(mi);  
  26.                                          }  
  27.                                 }  
  28.                       }  
  29.             }  
  30.     }  
  31.   
  32. //ScanClass.behavior()  
  33.     //扫描Method,如果发现HttpPathParameter注解,则加载RequestMapping。  



   

//构造ContractInfo

[java]  view plain  copy
  1. //根据以上两步结果,构造ContractInfo  
  2.           contractInfo =createContractInfo(contractClassInfos,behaviorClassInfos);  
  3.           //构造过程  
  4.           ContractInfocontractInfo = new ContractInfo();  
  5.           List<SessionBean>sessionBeanList = newArrayList<SessionBean>();  
  6.           for(ClassInfoc : contracts) {  
  7.                    SessionBeanbean = new SessionBean();  
  8.                    bean.setInterfaceClass(c);  
  9.                    bean.setInterfaceName(c.getCls().getName());  
  10.                    Map<String,String> implMap = newHashMap<String, String>();  
  11.                     
  12.                    //扫描和接口匹配的实现  
  13.                    for(ClassInfob : behaviors) {  
  14.                             Class<?>[]interfaceAry = b.getCls().getInterfaces();  
  15.                             for(Class<?>item : interfaceAry) {  
  16.                                       if(item ==c.getCls()) {  
  17.                                                implMap.put(b.getLookUP(),b.getCls().getName());  
  18.                                                break;  
  19.                                       }  
  20.                             }  
  21.                    }  
  22.                    bean.setInstanceMap(implMap);  
  23.                    sessionBeanList.add(bean);  
  24.           }  
  25.            
  26.           contractInfo.setSessionBeanList(sessionBeanList);  
  27.           return contractInfo;  



//创建ProxyClass

[java]  view plain  copy
  1. List<ClassFile> localProxyList = new ProxyClassCreater().createProxy(classLoader, serviceContract, time);  
  2.   
  3.   
  4.     //ProxyClassCreater.createProxy()  
  5.         String proxyClassName = lookup + "ProxyStub" + time;  
  6.   
  7.   
  8.         CtClass ctProxyClass = pool.makeClass(proxyClassName, null);  
  9.   
  10.   
  11.         ctProxyClass.addInterface(localProxy); // IProxyStub接口  
  12.   
  13.   
  14.         CtField proxyField = CtField.make( //构造实例  
  15. "private static " +sessionBean.getInterfaceName() +" serviceProxy = new " +implClassName +"();", ctProxyClass);  
  16.   
  17.   
  18.         ctProxyClass.addField(proxyField);  
  19.   
  20.   
  21.   
  22.   
  23.         //创建 method  
  24.         for(Method m : uniqueMethodList) {  
  25.             logger.debug("create method:" + m.getName());  
  26.             String methodStr = createMethods(proxyClassName, m.getName(), allMethodList, uniqueNameList);  
  27.             CtMethod methodItem = CtMethod.make(methodStr, ctProxyClass);  
  28.             ctProxyClass.addMethod(methodItem);  
  29.         }  
  30.   
  31.   
  32.         //创建invoke方法  
  33.         String invokeMethod = createInvoke(proxyClassName, uniqueNameList);  
  34.         logger.debug("create invoke method:" + invokeMethod);  
  35.         CtMethod invoke = CtMethod.make(invokeMethod, ctProxyClass);  
  36.         ctProxyClass.addMethod(invoke);  
  37.   
  38.   
  39.         clsList.add(new ClassFile(proxyClassName, ctProxyClass.toBytecode()));  
  40.     }  
  41.   
  42.     //Invoke方法体,使用到了GaeaResponse和GaeaContext  
  43.     private String createInvoke(String className, List<String> uniqueNameList) {  
  44.         StringBuilder sb = new StringBuilder();  
  45.         sb.append("public " + Constant.GAEARESPONSE_CLASS_NAME + " invoke(" + Constant.GAEACONTEXT_CLASS_NAME + " context) throws " + Constant.SERVICEFRAMEEXCEPTION_CLASS_NAME + " {");  
  46.         sb.append("String methodName = ((" + Constant.REQUEST_PROTOCOL_CLASS_NAME + ")context.getGaeaRequest().getProtocol().getSdpEntity()).getMethodName();");  
  47.         for (String methodName : uniqueNameList) {  
  48.             sb.append("if(methodName.equalsIgnoreCase(\"");  
  49.             sb.append(methodName);  
  50.             sb.append("\")){return ");  
  51.             sb.append(methodName);  
  52.             sb.append("(context);}");  
  53.         }  
  54.         sb.append("throw new " + Constant.SERVICEFRAMEEXCEPTION_CLASS_NAME + "(\"method:" + className + ".invoke--msg:not found method (\"+methodName+\")\", context.getChannel().getRemoteIP(), context.getChannel().getLocalIP(), context.getGaeaRequest().getProtocol().getSdpEntity(), " + Constant.ERRORSTATE_CLASS_NAME + ".NotFoundMethodException, null);");  
  55.         sb.append("}");  
  56.         return sb.toString();  
  57.     }  



// 创建 ProxyFactory

[java]  view plain  copy
  1. ClassFile cfProxyFactory = new ProxyFactoryCreater().createProxy(classLoader, serviceContract, time);  
  2.   
  3. IProxyFactory pfInstance = (IProxyFactory)constructor.newInstance(localProxyAry);  
  4. //constructor为ProxyFactory实例,里面初始化所有实例  

//gaea.init的init方法

[java]  view plain  copy
  1. // load init beans  
  2. loadInitBeans(classLoader, sc);  

//loadSecureKey 最终将配置文件中 //secure 信息添加到 Global.secureMap

[java]  view plain  copy
  1. loadSecureKey(sc,serviceFolderPath);  

// load servers

[java]  view plain  copy
  1. loadServers(classLoader, sc);  
  2. //建立gaea.servers[].implement实例并调用start  


主要工作总结如下:

解析gaea配置文件gaea_config.xml

添加jar包到系统Classloader

扫描deploy/{serviceName}下的jar包,根据@ServiceContract等注解建立实现类(SessionBean)和该实现类对应接口的映射关系。

创建SessionBean对应的代理ProxyStub,该代理类负责将调用转交给实现类,并在接口上对参数做一层包装。分别使用GaeaResponse和GaeaContext为返回、参数类型。

创建Proxy工厂类,包含了SessionBean实例。

加载Filter

加载SecureKey配置

调用配置文件gaea.init的方法

加载Server


Proxy工厂类其实是以后请求处理的入口,客户端请求经过包装后发送到服务器端,服务器端解析消息,Proxy工厂根据消息调用对应SessionBean的某个方法。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值