1. 感觉有点懒惰了,两天没有写了,今天继续分析guzz加载config-server信息,说直接点就是解析guzz.xml中config-server配置的properties
<config-server> <server class="org.guzz.config.LocalFileconfigserver"> <param name="resource" value="guzz_app.properties" /> </server> </config-server>主要就是加载guzz_app.properties
2. 还是在GuzzContextImpl的initFromMainConfig方法中找到下面的代码:
configserver = builder.loadconfigserver() ; if(configserver == null){ throw new GuzzException("config-server is not available.") ; }就是这里解析了config-server,进入到loadconfigserver,这里也是解析xml,和前面的差不多,找到下面的代码
configserver server = (configserver) BeanCreator.newBeanInstance(className) ; JavaBeanWrapper bw = BeanWrapper.createPOJOWrapper(server.getClass()) ;2.1 首先看第一句代码,这里是根据xml配置的class通过BeanCreator创建一个对象,类结构图:
在Guzz中只提供了这么一个实现类,但是也可以自己实现的,这里主要列出了2个重要的方法,都等下来看具体的实现。
2.2 接着看第二句代码,这里有出现了BeanWrapper,主要的作用是用于对POJO对象进行读写。BeanWrapper在初始化后会缓存bean的方法信息。就拿上面的2句代码来说明,我们通常配置文件创建了一个configserver,但是在具体运行的时刻而是实现类LocalFileconfigserver,而这个BeanWrapper就是可以获取到运行时刻的configserver的方法,这样不管是LocalFileconfigserver还是自己实现的configserver,都可以通过BeanWrapper知道运行时具体是哪个类,有哪些方法。BeanWrapper类结构图:
由于这里只用到了JavaBeanWrapper,我们就只看这个类,首先看下构造方法:
public JavaBeanWrapper(Class beanClass){ this.beanClass = beanClass ; BeanInfo bi; try { bi = Introspector.getBeanInfo(beanClass); } catch (IntrospectionException e) { throw new ORMException("fail to contruct beanwrapper:" + beanClass,e) ; } PropertyDescriptor[] pd = bi.getPropertyDescriptors(); //FIXME: cann't handle property:My_book_title for(int i = 0 ; i < pd.length ; i++){ this.propertyDescriptors.put(pd[i].getName(),pd[i]) ; } }只看红色的代码,首先获取到BeanInfo对象,然后获取到所有属性的PropertyDescriptor对象数组,循环吧数组中的每一个对象存放到map对象中,具体 PropertyDescriptor有什么东西,自己可以把写一个测试类打印下就知道了,主要是保存的是每一个属性,和这个属性的读写方法。只要看了构造方法其他的方法都可以不用看了,肯定是通过保存在map中的PropertyDescriptor对象进行的操作。
3. 接着回到GuzzConfigFileBuilder的loadconfigserver方法中,
List xml_params = e.selectNodes("param") ; for(int i = 0 ; i < xml_params.size() ; i++){ Element xml_param = (Element) xml_params.get(i) ; String propName = xml_param.attributeValue("name") ; String value = xml_param.attributeValue("value") ; if(Resource.class.isAssignableFrom(bw.getPropertyType(propName))){ FileResource fr = new FileResource(mainConfigResource,value) ; try{ bw.setValue(server,propName,fr) ; }finally{ CloseUtil.close(fr) ; } }else{ bw.setValue(server,value) ; } }这段代码就是解析param,文章开头已经写了我的配置,那么这里的propName的值就是resource,value就是guzz_app.properties,看红色的代码,调用JavaBeanWrapper的setValue方法,看这里要明确运行的时候各个变量具体代表什么,bw就是 JavaBeanWrapper对象,存的都是configserver的属性读写方法,而这里的configserver具体有时指LocalFileconfigserver;参数server具体也是LocalFileconfigserver。接着进入到setValue(...)
public void setValue(Object beanInstance,String propName,Object value){ PropertyDescriptor pd = (PropertyDescriptor) this.propertyDescriptors.get(propName) ; ... Method writeMethod = pd.getWriteMethod(); if (writeMethod != null) { try { writeMethod.invoke(beanInstance,new Object[]{value}); } catch (IllegalArgumentException e) { ... } }else{ throw new ORMException("property:" + propName + " not writable in :" + this.beanClass) ; } }首先通过属性名称获取到PropertyDescriptor,然后得到写的方法,接着调用方法,我们的属性名称是resource,那么写方法就是setResource,而对象又是 LocalFileconfigserver,所以我们就去看LocalFileconfigserver的setResource方法。
4.LocalFileconfigserver的setResource方法有调用了addResource,这也是要的实现方法:
protected void addResource(Resource r,boolean resourceMustBeValid){ Map props = PropertyUtil.loadGroupedProps(r) ; .... Iterator keys = props.entrySet().iterator() ; while(keys.hasNext()){ Map.Entry entry = (Entry) keys.next() ; String configGroupName = (String) entry.getKey() ; Properties[] ps = (Properties[]) entry.getValue() ; ServiceConfig[] scs = new ServiceConfig[ps.length] ; for(int i = 0 ; i < ps.length ; i++){ Properties p = ps[i] ; ServiceConfig sc = new ServiceConfig() ; scs[i] = sc ; sc.setConfigName(configGroupName) ; //读取系统配置项uniqueIdentifer appName serviceName IP maxLoad //剩下作为附件参数 sc.setUniqueIdentifer(p.getProperty("guzz.identifer")) ; sc.setIP(p.getProperty("guzz.IP")) ; sc.setMaxLoad(StringUtil.toInt(p.getProperty("guzz.maxLoad"),-1)) ; sc.setAppName(p.getProperty("guzz.appName")) ; ..... } configs.put(configGroupName,scs) ; } }第一段红色加粗的地方就是guzz在解析配置文件guzz_app.properties,把以中括号([...])开始的分为一个组,统一存放到一个Map,key就是中括号中的值,作为服务名,具体代码可以自己去看。剩下的一大段循环就是取出返回来的Map中的每一个对象(具体就是Properties),然后根据 Properties对象创建服务配置对象ServiceConfig,接着把ServiceConfig对象保存到全局Map对象中。 5.guzz加载config-server信息的过程分析完成。
原文地址:https://www.jb51.cc/xml/299265.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。