1, the preface

How does Spring load the Dubbo provider configuration based on annotation integration

2. Environment preparation

Clone dubbo 2.7.7 source code, run org. Apache. Dubbo. Demo. The provider. The application # main method

3. Spring loading process

Follow the previous step to get here:

1. Initialize the configuration

this(a);Copy the code

Static code blocks, static methods, constructors, etc.

2. Register the configuration class

ProviderConfiguration encapsulated into AnnotatedGenericBeanDefinition, and register to be kept in the Spring container

// Method path--> register(annotatedClasses); --> org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(java.lang.Class<? >, java.lang.String, java.lang.Class<? extends java.lang.annotation.Annotation>...) --> org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition --> org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinitionCopy the code

Will ConfigurationClassPostProcessor registered into the container, BeanName is org. Springframework. Context. The annotation. InternalConfigurationAnnotationProcessor

Part of the logic is as follows:

3. Container refresh

refresh();
Copy the code

This logic is also the core logic of Spring startup. The main operations are shown in the following figure:

invokeBeanFactoryPostProcessors(beanFactory)

The main logic is as follows:

/ executive BeanDefinitionRegistryPostProcessor * * * * * * 1, processing to achieve the first PriorityOrdered BeanDefinitionRegistryPostProcessor * interfaces 2, reprocessing realized Ordered interface BeanDefinitionRegistryPostProcessor * 3, the final treatment did not achieve the above two kinds of interface of other BeanDefinitionRegistryPostProcessors * * Implement the spring BeanFactoryPostProcessor, Get all the beans of the implementation class, 3, Processed BeanFactoryPostProcessor * that implements the PriorityOrdered interface, and then processed the Ordered interface BeanFactoryPostProcessor * */
Copy the code

Processing PriorityOrdered BeanDefinitionRegistryPostProcessor interface:

Among them, the PostProcessorRegistrationDelegate# invokeBeanFactoryPostProcessors method, Obtain beanName, depending on the type of BeanDefinitionRegistryPostProcessor filtered according to a series of conditions, the results as follows: Org. Springframework. Context. The annotation. InternalConfigurationAnnotationProcessor, corresponding bean as follows: ConfigurationClassPostProcessor (in step 2 injection) register configuration class 】 【

Get the beanName filter logic:

Perform invokeBeanDefinitionRegistryPostProcessors (currentRegistryProcessors, registry), follow the source to enter here:

ProcessConfigBeanDefinitions (registry) : the real meaning is: parsing Configuration class with @ the Configuration notes

The method mainly does the following things:1And filter out the belt@ConfigurationAnnotations BeanDefinitionHolder2And according to the@OrderThe values defined by the annotations are sorted in descending order3And recursively resolve each band@ConfigurationAnnotated class and generate BeanDefinition information4, parsing,@ImportRegistryAnnotate the class and generate a BeanDefinitionCopy the code

Step 3: Parse @configuration class logic:

Parser. parse(candidates) : Parses the configuration class and generates BeanDefinition information to register in the container

-> parser.parse(candidates);
	-> ConfigurationClassParser#parse(java.util.Set)
		-> #parse(AnnotationMetadata, java.lang.String)
        	-> #processConfigurationClass
        		-> #doProcessConfigurationClass
        			-> #processImports
Copy the code

This. Reader. LoadBeanDefinitions (configClasses) : load the configuration class generation BeanDefinition information

-> this.reader.loadBeanDefinitions(configClasses)
    -> ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
    	-> #loadBeanDefinitionsFromRegistrars
Copy the code

BeanDefinition DubboConfigConfigurationRegistrar registration:

Three main things have been done:1, registered DubboConfigConfiguration. Single. BeanDefinition information of the class2And according to the@EnableDubboConfigConfigure multiple attribute decision whether register DubboConfigConfiguration. Multiple. BeanDefinition information of the class3Register the Dubbo public BeanDefinition information (contains3Four Bean post-handlers,2Event listening)Copy the code

registerBeanPostProcessors(beanFactory)

Get all beans of type BeanPostProcessor and register them as implemented @priorityordered, @Ordered, and so on

initApplicationEventMulticaster()

Initialize the event multicast and register it with the container to publish the event to use

finishBeanFactoryInitialization(beanFactory)

Convert BeanDefinition information stored in the container to beans and register with the container; (This parsing process also involves a frequently asked Spring question: Spring loop dependencies.)

finishRefresh()

Complete container startup, publishing events, Dubbo listening by two listener: DubboLifecycleComponentApplicationListener, DubboBootstrapApplicationListener

-> finishRefresh() -> AbstractApplicationContext#publishEvent(ApplicationEvent) -> #publishEvent(java.lang.Object, org.springframework.core.ResolvableType) -> SimpleApplicationEventMulticaster#multicastEvent(ApplicationEvent,ResolvableType) -> #invokeListener -> #doInvokeListener -> DubboLifecycleComponentApplicationListener#onApplicationContextEvent -> #onContextRefreshedEvent ->  DubboBootstrapApplicationListener#onApplicationContextEvent -> #onContextRefreshedEvent -> org.apache.dubbo.config.bootstrap.DubboBootstrap#startCopy the code

Initialization DubboLifecycleComponentApplicationListener: Dubbo life-cycle related processes

DubboBootstrapApplicationListener: Dubbo bootstrap class, mainly perform the Provider service related processes

conclusion

  • This article briefly explained how the Dubbo provider service exposure process integrates with Spring
  • By writing this article, I have briefly reviewed the Spring loading process
  • With Dubbo’s integration with Spring, other frameworks should follow a similar pattern into the Spring lifecycle
  • Learn from the above experience and write some custom plug-ins