Dubbo source code analysis (5): dynamic compilation of Dubbo kernel implementation

The java code we run is generally compiled bytecode. In order to realize the extension characteristics based on the spi idea, Dubbo can flexibly add additional functions. For the selection of extensions or strategies, this class called a control class or a configuration class or a class should be able to be dynamically generated . Of course, it is okay to directly provide the configuration code dubbo corresponding to known requirements such as Protocol, ProxyFactory and their strategy selection, but as a highly scalable framework, dubbo enables users to add their own requirements and dynamically generate their own configuration according to the configuration. Class (control class) code, so you need to compile and load the code of this configuration class (control class) at runtime . Let's take a look at the dynamic compilation of Dubbo.

 

Class diagram for a dynamically compiled implementation:

Compile the interface definition:

@SPI("javassist")  
  
public interface Compiler {  
  
Class<?> compile(String code, ClassLoaderclassLoader);  
  
}  

The SPI annotation indicates that if there is no configuration, dubbo uses javassist to compile the source code by default

The first input parameter code of the interface method compile is the source code of java

The second input parameter of the interface method compile is the classLoader, which is supposed to be used by the class loader to load the compiled bytecode. In fact, it is not used. It is loaded according to the classLoader of the current thread or the caller.

package com.alibaba.dubbo.common.compiler;  
  
  
  
  
import com.alibaba.dubbo.common.extension.SPI;  
  
  
/** 
 * Compiler. (SPI, Singleton, ThreadSafe) 
 *  
 * @author william.liangf 
 */  
@SPI("javassist")  
public interface Compiler {  
  
  
<span style="white-space:pre">    </span>/** 
<span style="white-space:pre">    </span> * Compile java source code. 
<span style="white-space:pre">    </span> *  
<span style="white-space:pre">    </span> * @param code Java source code 
<span style="white-space:pre">    </span> * @param classLoader TODO 
<span style="white-space:pre">    </span> * @return Compiled class 
<span style="white-space:pre">    </span> */  
<span style="white-space:pre">    </span>Class<?> compile(String code, ClassLoader classLoader);  
  
  
}  
  
SPI注解表示如果没有配置,dubbo默认选用javassist编译源代码  
  
接口方法compile第一个入参code,就是java的源代码  
  
接口方法compile第二个入参classLoader,按理是类加载器用来加载编译后的字节码,其实没用到,都是根据当前线程或者调用方的classLoader加载的  
  
   
  
@Adaptive  
  
public class AdaptiveCompiler implements Compiler {  
  
    private static volatile String DEFAULT_COMPILER;  
  
    publicClass<?> compile(String code, ClassLoader classLoader) {  
  
        Compiler compiler;  
  
        ExtensionLoader<Compiler> loader= ExtensionLoader.getExtensionLoader(Compiler.class);  
  
        String name = DEFAULT_COMPILER;// copyreference  
  
        if (name !=null && name.length() > 0) {  
  
            compiler =loader.getExtension(name);  
  
        } else {  
  
            compiler =loader.getDefaultExtension();  
  
        }  
  
        return compiler.compile(code, classLoader);  
  
    }  
  
} 

    AdaptiveCompiler is the configuration class of Compiler. It has the class annotation @Adaptive to indicate that the configuration class (control class) of this Compiler is not generated by dynamic compilation. 

    The role of AdaptiveCompiler is the choice of strategy, which compilation strategy is selected according to the conditions to compile the dynamically generated source code.

    AbstractCompiler is a compiled abstract class, which abstracts the common logic. Here it mainly uses regular matching to the package name and class name in the source code, and then checks whether it exists in Class.forName in the jvm. If there is a reverse, it does not exist in the execution. Compile and load.

     The process of executing doCompile with JavassistCompiler and JdkCompiler is implemented by using the relevant api or extension interface provided by Javassit and Jdk.

Guess you like

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