How Dubbo's XML is used and how it integrates with Spring

Keywords: Dubbo Spring Apache xml

catalog

How Dubbo's XML is used and how it integrates with Spring

Dubbo's Service injection into spring is mainly org.apache.dubbo.config.spring.beans.factory.annotation.ServiceClassPostProcessor This class

ServiceClassPostProcessor

You can see the definition of this class:

public class ServiceClassPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
        ResourceLoaderAware, BeanClassLoaderAware {

    private final static List<Class<? extends Annotation>> serviceAnnotationTypes = asList(
            // @since 2.7.7 Add the @DubboService , the issue : https://github.com/apache/dubbo/issues/6007
            DubboService.class,
            // @since 2.7.0 the substitute @com.alibaba.dubbo.config.annotation.Service
            Service.class,
            // @since 2.7.3 Add the compatibility for legacy Dubbo's @Service , the issue : https://github.com/apache/dubbo/issues/4330
            com.alibaba.dubbo.config.annotation.Service.class
    );

            .................
            
        }

Implemented BeanDefinitionRegistryPostProcessor class

Bean definitionregistrypostprocessor provides the ability to dynamically register beans into containers. For details, please refer to https://blog.csdn.net/ztchun/article/details/90814135 This blog.

When Spring starts, it will call the refresh method of AbstractApplicationContext class. I will copy the code of the refresh method as follows:

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// The postProcessBeanFactory method of all beans in the container that implement the BeanFactoryPostProcessor interface will be called here,
				//BeanDefinitionRegistryPostProcessor implements this interface, so the method of ServiceClassPostProcessor class above will call
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

In the above notes, it has been explained that when spring is started, the instance method of ServiceClassPostProcessor in the container will be called to register all dubbo Service providers into the container;

How the bean instance of ServiceClassPostProcessor is injected into the container in advance.

At present, there are two ways for dubbo to integrate spring. One is to use beans.xml The other way is to use all the annotations of springboot. In fact, the principle of the two ways is the same.

Let me copy the following example of dubbo's spring usage on the official website:


Custom label used in picture< dubbo:....... >To configure some Dubbo attributes, there is a lot of knowledge about spring's custom labels. Here is just a brief introduction:

The figure shows the file in Dubbo source code. The file is configured with the following parsing classes for Dubbo custom labels: org.apache.dubbo.config.spring.schema.DubboNamespaceHandler

The definition of DubboNamespaceHandler, the parsing class of dubbo custom label, is as follows:

It is defined in the figure that the resolution class corresponding to each label is DubboBeanDefinitionParser, but the parameters passed in are different. The DubboBeanDefinitionParser class will put the first parameter passed in to generate BeanDefinition into the spring container. Here, the intersection of spring and dubbo is generated for the first time.

The Service tag will be parsed into Service bean class and put into the spring container, the Reference tag will be parsed into ReferenceBean class and put into the container, and the annotation beandefinitionparser class will scan @ Service and @ Reference annotation information in the project and generate the corresponding bean into the container.

AnnotationBeanDefinitionParser class source code

There are two methods for its source code, among which the registerCommonBeans method registers a bunch of time listeners and beanpostprocessors into the container. The registered beans are as follows:

*  ReferenceAnnotationBeanPostProcessor
*  DubboConfigDefaultPropertyValueBeanPostProcessor
*  DubboConfigAliasPostProcessor
*  DubboLifecycleComponentApplicationListener
*  DubboBootstrapApplicationListener

These five bean s are very important, which will be discussed in the following articles.

The getBeanClass method returns a ServiceAnnotationBeanPostProcessor class, which inherits from the ServiceClassPostProcessor class, so the ServiceClassPostProcessor class is added to the container.

Posted by Kower on Sat, 27 Jun 2020 21:27:35 -0700