当前位置: 首页 > news >正文

制作网站需要学什么软件有哪些软件系统开发报价表

制作网站需要学什么软件有哪些,软件系统开发报价表,谷歌推广开户,企业微信网站建设功能概述 为了减少反射的调用#xff0c;Dubbo会为每个服务提供者的实现生成一个Wrapper类#xff0c;通过Wrapper类去调用真正的接口实现类。 功能分析 核心类Wrapper分析 主要成员变量分析 private static final MapClass?, Wrapper WRAPPER_MAP ne…功能概述 为了减少反射的调用Dubbo会为每个服务提供者的实现生成一个Wrapper类通过Wrapper类去调用真正的接口实现类。 功能分析 核心类Wrapper分析 主要成员变量分析 private static final MapClass?, Wrapper WRAPPER_MAP new ConcurrentHashMapClass?, Wrapper(); //class wrapper map类与Wrapper的缓存当需要执行调用时根据Class即可找到Wrapper然后通过Wrapper调用目标对象中方法减少反射调用 private static final String[] EMPTY_STRING_ARRAY new String[0]; private static final String[] OBJECT_METHODS new String[] {getClass, hashCode, toString, equals}; private static final Wrapper OBJECT_WRAPPER new Wrapper() {...代码省略... }//Object对应的封装类匿名内部类主要成员方法分析 获取Wrapper封装类 public static Wrapper getWrapper(Class? c) { //获取Wrapper的实例先从缓存中获取若没有则对应创建while (ClassGenerator.isDynamicClass(c)) // can not wrapper on dynamic class.{c c.getSuperclass(); //不能封装动态类动态类取它的父类进行封装}if (c Object.class) { //Object 返回默认的对象封装类return OBJECT_WRAPPER;}return WRAPPER_MAP.computeIfAbsent(c, key - makeWrapper(key)); //构建封装类并设置到缓存中key的值与c相同 }创建封装类 private static Wrapper makeWrapper(Class? c) { //为指定class构建Wrapper封装类的实例if (c.isPrimitive()) { //基本类型不能创建封装类throw new IllegalArgumentException(Can not create wrapper for primitive type: c);}String name c.getName(); //被封装的类的全限定名如org.apache.dubbo.demo.GreetingServiceClassLoader cl ClassUtils.getClassLoader(c); //获取类加载器// 拼接类代码对应的字符串 (对应Wrapper类中的抽象方法)StringBuilder c1 new StringBuilder(public void setPropertyValue(Object o, String n, Object v){ ); //构建当前类中的setPropertyValue()抽象方法StringBuilder c2 new StringBuilder(public Object getPropertyValue(Object o, String n){ );StringBuilder c3 new StringBuilder(public Object invokeMethod(Object o, String n, Class[] p, Object[] v) throws InvocationTargetException.class.getName() { );c1.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }); //将setPropertyValue方法中的Object强制转化为具体类型如(org.apache.dubbo.demo.GreetingService)$1c2.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }); //将getPropertyValue方法中的Object强制转化为具体类型c3.append(name).append( w; try{ w (().append(name).append()$1); }catch(Throwable e){ throw new IllegalArgumentException(e); }); //将invokeMethod方法中的Object强制转化为具体类型MapString, Class? pts new HashMap(); // property name, property types 属性名与属性类型的映射MapMapString, Method ms new LinkedHashMap(); // method desc, Method instance 方法对应的描述符与方法实例的映射MapListString mns new ArrayList(); // method names. 方法名列表ListString dmns new ArrayList(); // declaring method names. 被封装的类或接口中声明的方法名列表// get all public field.for (Field f : c.getFields()) { //处理被封装类的所有public字段String fn f.getName(); //获取字段名称Class? ft f.getType(); //获取字段类型如 java.lang.Stringif (Modifier.isStatic(f.getModifiers()) || Modifier.isTransient(f.getModifiers())) { //static、transient修饰的字段不处理接口中的字段都是public static final字段所以不会处理那这里处理就是对类封装时处理continue;}c1.append( if( $2.equals(\).append(fn).append(\) ){ w.).append(fn).append().append(arg(ft, $3)).append(; return; }); //通过setPropertyValue方法为目标对象设置成员属性的值如if( $2.equals(employeeName) ){ w.employeeName(java.lang.String)$3;c2.append( if( $2.equals(\).append(fn).append(\) ){ return ($w)w.).append(fn).append(; }); //通过getPropertyValue方法获取目标对象的成员变量值如if( $2.equals(employeeName) ){ return ($w)w.employeeName; }pts.put(fn, ft); //设置成员属性名与属性类型的关系如MapemployeeName,java.lang.String}Method[] methods c.getMethods();// get all public method.boolean hasMethod hasMethods(methods); //处理被封装类的所有public方法判断是否有非Object中的方法if (hasMethod) { //拼接invokeMethod方法中的调用逻辑把被封装的类或接口中的声明方法依次拼接起来c3.append( try{);for (Method m : methods) { //对类中的方法依次封装处理构造Wrapper中的invokeMethod方法如org.apache.dubbo.demo.GreetingService中声明中的所有方法//ignore Objects method.忽略Object对象中的方法if (m.getDeclaringClass() Object.class) {continue;}String mn m.getName();c3.append( if( \).append(mn).append(\.equals( $2 ) ); //$2指当前类中的invokeMethod()的第二个参数比较方法名称int len m.getParameterTypes().length;c3.append( ).append( $3.length ).append(len);// 比较方法参数个数需要方法名称和参数个数都相等boolean override false; //判断同一个接口或类中是存在重载的方法for (Method m2 : methods) { //按方法名判断是否重写if (m ! m2 m.getName().equals(m2.getName())) {override true;break;}}if (override) { //若有重载的方法只按方法名称不能匹配出方法还得按参数类型进行匹配if (len 0) { //方法参数个数for (int l 0; l len; l) { //c3.append( ).append( $3[).append(l).append(].getName().equals(\).append(m.getParameterTypes()[l].getName()).append(\));}}}c3.append( ) { ); //组装出判断条件如if( hello.equals( $2 ) $3.length 1 $3[0].getName().equals(org.apache.dubbo.demo.Fruit))if (m.getReturnType() Void.TYPE) { //返回类型为voidc3.append( w.).append(mn).append(().append(args(m.getParameterTypes(), $4)).append();).append( return null;);} else { //方法有返回类型组装方法的返回类型如return ($w)w.hello((org.apache.dubbo.demo.Fruit)$4[0] c3.append( return ($w)w.).append(mn).append(().append(args(m.getParameterTypes(), $4)).append(););}c3.append( });mns.add(mn); //加入到方法名列表if (m.getDeclaringClass() c) {dmns.add(mn); //被封装的类或接口中声明的方法}ms.put(ReflectUtils.getDesc(m), m); //将方法描述符与方法实例缓存起来}c3.append( } catch(Throwable e) { );c3.append( throw new java.lang.reflect.InvocationTargetException(e); );c3.append( });}c3.append( throw new NoSuchMethodException.class.getName() (\Not found method \\\\$2\\\\ in class c.getName() .\); }); //若没有找到方法则抛出“未找到方法”的异常// deal with get/set method.处理set/get方法非规范的方法就不会处理了Matcher matcher;for (Map.EntryString, Method entry : ms.entrySet()) {String md entry.getKey(); //暴露接口中的方法描述信息如hello(Lorg/apache/dubbo/demo/FruitEnum;)Ljava/lang/String;Method method entry.getValue();if ((matcher ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) { //判断是否匹配get方法对应的描述信息描述信息可以确定唯一的方法String pn propertyName(matcher.group(1));c2.append( if( $2.equals(\).append(pn).append(\) ){ return ($w)w.).append(method.getName()).append((); });pts.put(pn, method.getReturnType());} else if ((matcher ReflectUtils.IS_HAS_CAN_METHOD_DESC_PATTERN.matcher(md)).matches()) { //匹配is、has、can方法String pn propertyName(matcher.group(1));c2.append( if( $2.equals(\).append(pn).append(\) ){ return ($w)w.).append(method.getName()).append((); });pts.put(pn, method.getReturnType());} else if ((matcher ReflectUtils.SETTER_METHOD_DESC_PATTERN.matcher(md)).matches()) { //匹配set方法Class? pt method.getParameterTypes()[0];String pn propertyName(matcher.group(1));c1.append( if( $2.equals(\).append(pn).append(\) ){ w.).append(method.getName()).append(().append(arg(pt, $3)).append(); return; }); //拼接的内容如 if( $2.equals(msg) ){ w.setMsg((java.lang.String)$3); return;pts.put(pn, pt); //设置属性名与属性Class的映射}}c1.append( throw new NoSuchPropertyException.class.getName() (\Not found property \\\\$2\\\\ field or setter method in class c.getName() .\); });c2.append( throw new NoSuchPropertyException.class.getName() (\Not found property \\\\$2\\\\ field or setter method in class c.getName() .\); });// make class构建Class对象long id WRAPPER_CLASS_COUNTER.getAndIncrement();ClassGenerator cc ClassGenerator.newInstance(cl); //使用ClassGenerator类生成器来生成Wrapper的Classcc.setClassName((Modifier.isPublic(c.getModifiers()) ? Wrapper.class.getName() : c.getName() $sw) id); //org.apache.dubbo.common.bytecode.Wrapper0判断类是否是public然后进行类名拼接cc.setSuperClass(Wrapper.class); //将Wrapper指定为父类创建其封装类cc.addDefaultConstructor(); //添加默认构造函数cc.addField(public static String[] pns;); // property name array.cc.addField(public static Map.class.getName() pts;); // property type map.cc.addField(public static String[] mns;); // all method name array.cc.addField(public static String[] dmns;); // declared method name array.for (int i 0, len ms.size(); i len; i) {cc.addField(public static Class[] mts i ;);}cc.addMethod(public String[] getPropertyNames(){ return pns; });cc.addMethod(public boolean hasProperty(String n){ return pts.containsKey($1); });cc.addMethod(public Class getPropertyType(String n){ return (Class)pts.get($1); });cc.addMethod(public String[] getMethodNames(){ return mns; });cc.addMethod(public String[] getDeclaredMethodNames(){ return dmns; });cc.addMethod(c1.toString()); //处理setPropertyValue()方法cc.addMethod(c2.toString()); //处理getPropertyValue()方法cc.addMethod(c3.toString()); //处理invokeMethod()方法try {Class? wc cc.toClass(); //将CtClass转换为Class// setup static field.设置静态字段值wc.getField(pts).set(null, pts);wc.getField(pns).set(null, pts.keySet().toArray(new String[0]));wc.getField(mns).set(null, mns.toArray(new String[0]));wc.getField(dmns).set(null, dmns.toArray(new String[0]));int ix 0;for (Method m : ms.values()) { //遍历方法参数列表wc.getField(mts ix).set(null, m.getParameterTypes());}return (Wrapper) wc.newInstance(); //使用Class对象创建实例并强转为Wrapper类型} catch (RuntimeException e) {throw e;} catch (Throwable e) {throw new RuntimeException(e.getMessage(), e);} finally {cc.release();ms.clear();mns.clear();dmns.clear();} }关联类ClassGenerator分析 主要成员变量分析 private static final AtomicLong CLASS_NAME_COUNTER new AtomicLong(0); //未指定类名时默认产生类名用到的下标 private static final String SIMPLE_NAME_TAG init; private static final MapClassLoader, ClassPool POOL_MAP new ConcurrentHashMapClassLoader, ClassPool(); //ClassLoader - ClassPool类加载器与javassist中的类池对应缓存 private ClassPool mPool; //javassist中的类池 private CtClass mCtc; //javassist中的编译时类 private String mClassName; //动态生成的类名 private String mSuperClass; //父类对应的名称 private SetString mInterfaces; //存放类实现的接口列表 private ListString mFields; //存放字段对应的代码片段如ccp.addField(public static java.lang.reflect.Method[] methods;); private ListString mConstructors; //存放构造函数对应的代码片段 private ListString mMethods; //存放方法对应的代码片段 private MapString, Method mCopyMethods; // method desc,method instance 方法描述符与方法实例的映射 private MapString, Constructor? mCopyConstructors; // constructor desc,constructor instance 方法描述符与构造实例的映射 private boolean mDefaultConstructor false; //是否使用默认构造函数主要成员方法分析 动态创建Class对象 public Class? toClass(ClassLoader loader, ProtectionDomain pd) { //创建Class对象将当前维护的Class信息创建Class对象if (mCtc ! null) {mCtc.detach(); //detach:分离 从ClassPool中移除CtClass}// 基于当前类维护的数据进行逻辑处理long id CLASS_NAME_COUNTER.getAndIncrement();try {CtClass ctcs mSuperClass null ? null : mPool.get(mSuperClass); // 从类池ClassPool中获取类名mSuperClass对应的CtClassif (mClassName null) { //若没显示设置类名时自动生成对应的类名如 org.apache.dubbo.common.bytecode.ClassGenerator0mClassName (mSuperClass null || javassist.Modifier.isPublic(ctcs.getModifiers()) // ||都优先级大于?: 且结合性是从左到右的? ClassGenerator.class.getName() : mSuperClass $sc) id; //构建类名取ClassGenerator名称或mSuperClass名称}mCtc mPool.makeClass(mClassName); //根据类名className创建对应的CtClass对象if (mSuperClass ! null) { // 设置继承的类java是单继承所以只会设置一个父类mCtc.setSuperclass(ctcs);}mCtc.addInterface(mPool.get(DC.class.getName())); // add dynamic class tag. (每一个动态类都实现了DC接口)if (mInterfaces ! null) { // 设置实现的接口for (String cl : mInterfaces) {mCtc.addInterface(mPool.get(cl));}}if (mFields ! null) { // 设置字段for (String code : mFields) {mCtc.addField(CtField.make(code, mCtc)); // 将字段对应的字符串转换为CtField}}if (mMethods ! null) { // 设置方法for (String code : mMethods) {if (code.charAt(0) :) {mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))),code.substring(1, code.indexOf(()), mCtc, null));} else {mCtc.addMethod(CtNewMethod.make(code, mCtc)); // 将方法对应的字符串转换为CtMethod}}}if (mDefaultConstructor) { // 设置默认的构造函数无参的构造函数mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));}if (mConstructors ! null) { // 处理构造函数for (String code : mConstructors) {if (code.charAt(0) :) {mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null));} else {String[] sn mCtc.getSimpleName().split(\\$); // inner class name include $.mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length - 1]), mCtc));}}}return mCtc.toClass(loader, pd); //使用CtClass转换到Class} catch (RuntimeException e) {throw e;} catch (NotFoundException e) {throw new RuntimeException(e.getMessage(), e);} catch (CannotCompileException e) {throw new RuntimeException(e.getMessage(), e);} }代码解析动态创建Class的流程 将设置的代码字符串如继承的类、实现的接口、设置的方法、字段等转换javassist对应的数据模型如CtMethod、CtFiled等然后按类或接口的组成进行组装如设置继承的类、设置实现的接口、设置类中的方法和字段等使用javassist的CtClass.toClass()获取到动态生成的Class类似Mybatis的动态SQL按字符串动态组装最终形成SQL 问题点答疑 每个暴露的接口都有一个wrapper封装类吗是怎么找到这个Wrapper类的 解答在服务暴露时ServiceConfig#doExportUrlsFor1Protocol会Wrapper.getWrapper(interfaceClass).getMethodNames()为暴露的接口创建Wrapper类并对应缓存起来。消费端ReferenceConfig#init也会在启动时创建接口对应的Wrapper类并对应缓存起来。会转换为具体的类进行执行避免了反射使用 Wrapper能够获取类的封装类吗还是说只能获取接口的封装类 解答不管是接口还是类都可以创建其对应的封装类的 归纳总结 Wrapper用于“包裹”目标类Wrapper是一个抽象类仅可通过 getWrapper(Class) 方法创建子类。在创建Wrapper子类的过程中子类代码生成逻辑会对getWrapper方法传入的Class对象进行解析拿到诸如类方法类成员变量等信息。以及生成 invokeMethod方法代码和其他一些方法代码。代码生成完毕后通过 Javassist 生成 Class 对象最后再通过反射创建Wrapper实例 ClassGeneratorClass生成器内部对Javassist的数据模型进行抽象对外提供使用代码片段的方式创建Class
http://www.zqtcl.cn/news/866438/

相关文章:

  • 深圳品牌做网站公司有哪些公司名称变更网站要重新备案吗
  • 网站网页建设实训心得体会二类电商平台都有哪些
  • 兰州免费网站建设上海城隍庙要门票吗
  • 如何做外贸soho做网站中型网站建设
  • 冠县品牌网站建设推广外贸企业网站管理系统
  • 信息管理的基本原理分析网站建设南阳网站建设制作
  • 网站一直百度上搜不到是怎么回事啊网站建设首保服务
  • 解决网站兼容性问题福州房产网站建设
  • 怀化百度整站优化服务wap网站前景
  • 临沂制作网站企业施工企业汛期工作实施方案
  • 82家合法现货交易所名单永康关键词优化
  • 郑州市建设工程造价信息网站浙江省建设工程质量管理协会网站
  • 乌兰浩特市建设局网站永州微网站建设
  • 做网站的用什么电脑好wordpress首页调用指定分类
  • 网站域名申请好了怎么建设网站室内设计培训班哪个学校好
  • 东莞厚街网站建设网页设计代码字号px
  • 网站建站免费淘宝优惠券网站建设总代
  • 茶叶网站设计建设工程监理招标网站
  • 网站建设发展历程做网站要多少钱 知乎
  • 丽江建设信息网站江门网站制作方案
  • 网站名注册移动端应用开发
  • 本地网站搭建流程短链接生成器app
  • 建网站需要哪些技术代做ppt网站
  • 在上海哪个网站比较好网站建设服务方案ppt模板
  • 天津网站优化流程uniapp微信小程序模板
  • 网站 搜索引擎 提交企业网站必须备案
  • 公司网站主页设计深圳搜索引擎
  • 织梦学校网站中国建设银行官方网站诚聘英才频道
  • 织梦网站去除技术支持网站建设热门吗
  • 手机自助网站建设电商首页设计