Dubbo source code analysis 2-- JavassistProxyFactory

agency factory

@SPI("javassist")
public interface ProxyFactory {


    @Adaptive({Constants.PROXY_KEY})
    <T> T getProxy(Invoker<T> invoker) throws RpcException;


    @Adaptive({Constants.PROXY_KEY})
    <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;

}

proxyFactory There are three classes JavassistProxyFactory, JavassistProxyFactory and StubProxyFactoryWrapper

StubProxyFactoryWrapper is the decorator of the proxy factory. By default, JavassistProxyFactory is used to generate bytecode to create objects

private static final Protocol protocol = ExtensionLoader.
    getExtensionLoader(Protocol.class).getAdaptiveExtension();
private static final ProxyFactory proxyFactory = ExtensionLoader.
    getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();

//ref是具体的类com.TestServiceImpl,而interfaceClass是com.ITestService.
Exporter<?> exporter = protocol.export(
      proxyFactory.getInvoker(ref, (Class) interfaceClass, local));

The previous section mentioned that the AdaptiveExtension that generates the ProxyFactory generates code, and it defaults to JavassistProxyFactory.
Bytecode technology generates proxies.

  • Generate a Wrapper object (the most important method in it is invokeMethod)
  • Returns an AbstractProxyInvoker object
public class JavassistProxyFactory extends AbstractProxyFactory {

    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
        return (T) Proxy.getProxy(interfaces).newInstance(new 
            InvokerInvocationHandler(invoker));
    }

    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // TODO Wrapper类不能正确处理带$的类名
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().
            indexOf('$') < 0 ? proxy.getClass() : type);
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName, 
                                      Class<?>[] parameterTypes, 
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod
                (proxy, methodName, parameterTypes, arguments);
            }
        };
    }

}

The invoke of AbstractProxyInvoker actually calls the wrapper.invokeMethod method


 public Result invoke(Invocation invocation) throws RpcException {
      try {
          return new RpcResult(doInvoke(proxy, invocation.getMethodName(), 
          invocation.getParameterTypes(), invocation.getArguments()));
      } catch (InvocationTargetException e) {
          return new RpcResult(e.getTargetException());
      } catch (Throwable e) {
          throw new RpcException("...");
      }
  }

Get the Wrapper object

//放在缓存里WRAPPER_MAP
Map<Class<?>, Wrapper> WRAPPER_MAP = new ConcurrentHashMap<Class<?>, Wrapper>();
public static Wrapper getWrapper(Class<?> c){
   while( ClassGenerator.isDynamicClass(c) )
        c = c.getSuperclass();

    if( c == Object.class )
        return OBJECT_WRAPPER;

    Wrapper ret = WRAPPER_MAP.get(c);
    if( ret == null ){
        ret = makeWrapper(c);
        WRAPPER_MAP.put(c,ret);
    }
    return ret;
}

BusinessNoGeneratorService business class

eg: Now there is such a class BusinessNoGeneratorService, which needs to be packaged as Wrapper

public interface BusinessNoGeneratorService {
    String getNewOrderNo(String var1);

    String getOrderNoForRenew(String var1, String var2);

    String getNonAutoOrderNo();

    String getPushRepairTaskNo();

    String getInsurerSettlementFileBatchNo();

    String getDealerGAPContractNo(String var1);

    Long getBusinessNo(String var1, String var2, String var3,
     String var4, String var5);
}

All methods in the source code of the generated Wrapper object (assembling BusinessNoGeneratorService)

public String[] getPropertyNames(){ return pns; }
public boolean hasProperty(String n){ return pts.containsKey($1); }
public Class getPropertyType(String n){ return (Class)pts.get($1); }
public String[] getMethodNames(){ return mns; }
public String[] getDeclaredMethodNames(){ return dmns; }
public void setPropertyValue(Object o, String n, Object v){ 
    com.insaic.itbase.service.BusinessNoGeneratorService w; 
    try{ 
        w = ((com.insaic.itbase.service.BusinessNoGeneratorService)$1); 
    }catch(Throwable e){ 
        throw new IllegalArgumentException(e); 
    } 
    throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException(".."); 
}
public Object getPropertyValue(Object o, String n){ 
    com.insaic.itbase.service.BusinessNoGeneratorService w; 
    try{ 
        w = ((com.insaic.itbase.service.BusinessNoGeneratorService)$1); 
    }catch(Throwable e){ 
        throw new IllegalArgumentException(e); 
    } 
    if( $2.equals("nonAutoOrderNo") ){
        return ($w)w.getNonAutoOrderNo(); 
    } 
    if( $2.equals("pushRepairTaskNo") ){ 
        return ($w)w.getPushRepairTaskNo();
    } 
    if( $2.equals("insurerSettlementFileBatchNo") ){ 
        return ($w)w.getInsurerSettlementFileBatchNo();
    } 
    throw new com.alibaba.dubbo.common.bytecode.NoSuchPropertyException(".."); 
}
//主要是这个。
public Object invokeMethod(Object o, String n, Class[] p, Object[] v) 
throws java.lang.reflect.InvocationTargetException{ 
    com.insaic.itbase.service.BusinessNoGeneratorService w;
    try{ 
        w = ((com.insaic.itbase.service.BusinessNoGeneratorService)$1);
    }catch(Throwable e){ 
        throw new IllegalArgumentException(e); 
    } 
    try{ 
        if( "getBusinessNo".equals( $2 )  &&  $3.length == 5 ) {  
            return ($w)w.getBusinessNo((java.lang.String)$4[0],(java.lang.String)
            $4[1],
            (java.lang.String)$4[2],(java.lang.String)$4[3],(java.lang.String)$4[4]);
        } 
        if( "getNewOrderNo".equals( $2 )  &&  $3.length == 1 ) {  
            return ($w)w.getNewOrderNo((java.lang.String)$4[0]); 
        }
        if( "getOrderNoForRenew".equals( $2 )  &&  $3.length == 2 ) { 
            return ($w)w.getOrderNoForRenew((java.lang.String)$4[0],
            (java.lang.String)$4[1]);
        } 
        if( "getNonAutoOrderNo".equals( $2 )  &&  $3.length == 0 ) {  
            return ($w)w.getNonAutoOrderNo();
        } 
        if( "getPushRepairTaskNo".equals( $2 )  &&  $3.length == 0 ) {  
            return ($w)w.getPushRepairTaskNo(); 
        } 
        if( "getInsurerSettlementFileBatchNo".equals( $2 )  &&  $3.length == 0 ) { 
            return ($w)w.getInsurerSettlementFileBatchNo(); 
        } 
        if( "getDealerGAPContractNo".equals( $2 )  &&  $3.length == 1 ) {  
            return ($w)w.getDealerGAPContractNo((java.lang.String)$4[0]); 
        }
    } catch(Throwable e) {      
        throw new java.lang.reflect.InvocationTargetException(e); 
    } 
    throw new com.alibaba.dubbo.common.bytecode.NoSuchMethodException(".."); 

}

Generate Wrapper source code

private static Wrapper makeWrapper(Class<?> c){
    if( c.isPrimitive() )
        throw new IllegalArgumentException("..");

    String name = c.getName(); //com.insaic.itbase.service.BusinessNoGeneratorService
    ClassLoader cl = ClassHelper.getClassLoader(c);

//组装方法开始

    //设置属性
    StringBuilder c1 = new StringBuilder("public void setPropertyValue(Object o
    , String n, Object v){ ");
    //获取属性
    StringBuilder c2 = new StringBuilder("public Object getPropertyValue(Object o
    , String n){ ");
    //invokeMethod
    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); }");
    c2.append(name).append(" w; try{ w = ((").append(name).append(")$1); 
        }catch(Throwable e){ throw new IllegalArgumentException(e); }");
    c3.append(name).append(" w; try{ w = ((").append(name).append(")$1); 
        }catch(Throwable e){ throw new IllegalArgumentException(e); }");
    // 属性名称,属性类型<property name, property types>
    Map<String, Class<?>> pts = new HashMap<String, Class<?>>(); 
    //  方法描述,方法对象<method desc, Method instance>
    Map<String, Method> ms = new LinkedHashMap<String, Method>();
    // 方法名称 
    List<String> mns = new ArrayList<String>(); 
    List<String> dmns = new ArrayList<String>(); 

    //遍历类的字段
    for( Field f : c.getFields() )
        String fn = f.getName();
        Class<?> ft = f.getType();
        if( Modifier.isStatic(f.getModifiers()) || 
        Modifier.isTransient(f.getModifiers()) )
            continue;

        c1.append(" if( $2.equals(\"").append(fn).append("\") ){ 
        w.").append(fn).append("=").append(arg(ft, "$3")).append("; return; }");
        c2.append(" if( $2.equals(\"").append(fn).append("\") ){ return 
        ($w)w.").append(fn).append("; }");
        pts.put(fn, ft);
    }
    //遍历所有的方法
    Method[] methods = c.getMethods();
    boolean hasMethod = hasMethods(methods);
    if( hasMethod ){
        c3.append(" try{");
    }

    //组装invokeMethod
    for( Method m : methods ) {
        if( m.getDeclaringClass() == Object.class ) /
            continue;

        //组装invokeMethod    
        String mn = m.getName();
        c3.append(" if( \"").append(mn).append("\".equals( $2 ) ");

        //参数个数
              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( m.getReturnType() == Void.TYPE )
            c3.append(" w.").append(mn).append('(').append(args(
            m.getParameterTypes(), 
            "$4")).append(");").append(" return null;");
        else
            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);//方法描述和方法对象
    }
    if( hasMethod ){
        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() + ".\"); }");


    Matcher matcher;
    for( Map.Entry<String,Method> entry : ms.entrySet() ) {
    // getOrderNoForRenew(Ljava/lang/String;Ljava/lang/String;)
    //Ljava/lang/String;
        String md = entry.getKey();
        Method method = (Method)entry.getValue();

        if( ( matcher = ReflectUtils.GETTER_METHOD_DESC_PATTERN.matcher(md) 
        ).matches() ){
            //这个方法是get开头, 组装getPropertyValue
            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() )   
            String pn = propertyName(matcher.group(1));
            //方法是is或者has或者can,组装getPropertyValue
            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开头,组装setPropertyValue方法
            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; }");
            pts.put(pn, pt);
        }
    }

    c1.append(" throw new " + NoSuchPropertyException.class.getName() 
    + "(\"Not found property \\\"\"+$2+\"\\\" filed or 
    + setter method in class " + c.getName() + ".\"); }");
    c2.append(" throw new " + NoSuchPropertyException.class.getName()
     + "(\"Not found property \\\"\"+$2+\"\\\" filed or setter method 
     + in class " + c.getName() + ".\"); }");


//组装方法结束

    long id = WRAPPER_CLASS_COUNTER.getAndIncrement();

    ClassGenerator cc = ClassGenerator.newInstance(cl);
    //
    cc.setClassName( ( Modifier.isPublic(c.getModifiers()) ? 
    Wrapper.class.getName() :c.getName() + "$sw" ) + id );

    //类是Wrapper
    cc.setSuperClass(Wrapper.class);

    //设置属性和方法
    cc.addDefaultConstructor();
    cc.addField("public static String[] pns;"); 
    cc.addField("public static " + Map.class.getName() + " pts;"); 
    cc.addField("public static String[] mns;"); 
    cc.addField("public static String[] dmns;"); 
    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());
    cc.addMethod(c2.toString());
    cc.addMethod(c3.toString());


    Class<?> wc = cc.toClass();
        // 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;

    //创建
    Class<?> wc = cc.toClass();
    // 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();
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324894419&siteId=291194637