Dubbo source code implementation 1: cut into Spring

        Dubbo is a high-performance service framework open sourced by Alibaba, which provides functions such as service registration, RPC service invocation, invocation balance, service monitoring, and service failover. If you have not used the Dubbo framework, please refer to the official documents provided by dubbo, such as: http://www.oschina.net/p/dubbo?fromerr=iVZFqWON.

        There are two important roles in the Dubbo framework: (service) provider and (service) consumer. For the sake of simplicity, the application modules that include dubbo provider or consumer functions are generally referred to as dubbo clients .

        Look at the source code with a problem, and you can gain something.

        Getting to the point, most java applications are now inseparable from Spring, so other java solutions will more or less support the use in Spring, and dubbo is no exception. In my memory, any framework that wants to play a role in the Spring container is nothing more than providing the corresponding Spring Bean to inject into the Spring container, and the same is true for dubbo. In the dubbo-container-spring module of the source code, the only class SpringContainer illustrates this, and its start() method starts the Spring container directly through ClassPathXmlApplicationContext. Someone will immediately ask, who calls the start() method of SpringContainer? The answer is com.alibaba.dubbo.container.Main, which is the entrance of dubbo. The main method in the Main class will call the start() method of the built-in Container of dubbo in turn. If the path to the Spring xml file is not configured, dubbo will default to classpath*:META-INF/spring/*.xml.

         So the question is, how does Spring identify those custom tags of dubbo? In order to support the loading of user-defined classes into the Spring container, Spring provides the org.springframework.beans.factory.xml.NamespaceHandler interface and the org.springframework.beans.factory.xml.NamespaceHandlerSupport abstract class. The NamespaceHandler#init method will be used in the construction of the object. Called by DefaultNamespaceHandlerResolver after the function is called but before the property is initialized. Dubbo's DubboNamespaceHandler class inherits NamespaceHandlerSupport, and its code is implemented as follows:

public class DubboNamespaceHandler extends NamespaceHandlerSupport {

	static {
		Version.checkDuplicate(DubboNamespaceHandler.class);
	}

	public void init() {
	    registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
    }

}

        The registerBeanDefinitionParser method has the default implementation of the parent abstract class NamespaceHandlerSupport. The first parameter is elementName, which is the element name, which tells Spring which tag you want to parse. The second parameter is the implementation class of BeanDefinitionParser. BeanDefinitionParser is used by Spring to convert xml elements Converted to the interface of the BeanDefinition object. Dubbo's DubboBeanDefinitionParser class implements this interface and is responsible for converting labels into bean definition objects BeanDefinition. dubbo sets the following properties on the BeanDefinition it returns:

        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);

        beanDefinition.getPropertyValues().addPropertyValue("id", id);

        If it is the dubbo:protocol tag, dubboh will also check all beans that already contain the BeanDefinition of the protocol attribute and the value corresponding to the protocol attribute is the ProtocolConfig object, and set the protocol value of the attribute to the current bean reference:

        definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));

        If it is the dubbo:service tag of the dubbo service provider, the ref attribute will also be set to the implementation class bean of the corresponding interface class:

        beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));

        Has anyone thought, when using the dubbo:service tag of the dubbo service provider, if I set neither the id nor the name, what is the ID defined in the Spring container by dubbo to its ServiceBean? The answer is:

            if (generatedBeanName == null || generatedBeanName.length() == 0) {
                generatedBeanName = beanClass.getName();
            }
            id = generatedBeanName;
            int counter = 2;
            while(parserContext.getRegistry().containsBeanDefinition(id)) {
                id = generatedBeanName + (counter ++);
            }

        Some people will ask, how does Spring know that you have customized the implementation class of NamespaceHandlerSupport? The Spring container will load the spring.handlers and spring.schemas files under classpath/META-INF by default to load the namespace handler and xsd, so these two files are in the META-INF directory under the dubbo-config-spring package .

        Finally, the static code block in the DubboNamespaceHandler class goes to the classpath to check if there are other classes with the same name, otherwise an error log will be logged. Why is this? Prevent duplicate loading of DubboNamespaceHandler by different classloaders? unknown.

 

     

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327097457&siteId=291194637