Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.0] Improve dubbo config beans and bootstrap initialization #8168

Merged
merged 7 commits into from Jul 10, 2021

Conversation

kylixs
Copy link
Member

@kylixs kylixs commented Jun 29, 2021

What is the purpose of the change

Initialize dubbo config beans before spring singleton beans.
Initialize dubbo bootstrap after loaded config beans, before Spring context refreshed event.

New dubbo initialization flow:

=> AbstractApplicationContext#refresh()
   => AbstractApplicationContext#invokeBeanFactoryPostProcessors()
       => ServiceAnnotationPostProcessor.postProcessBeanFactory() 
       => ReferenceAnnotationBeanPostProcessor.postProcessBeanFactory() 
             publish event DubboAnnotationInitedEvent
   => AbstractApplicationContext#registerBeanPostProcessors()
   => AbstractApplicationContext#registerListeners()
         multicastEvent DubboAnnotationInitedEvent
         load DubboBootstrapApplicationListener
         process event DubboAnnotationInitedEvent (DubboBootstrapApplicationListener#onApplicationEvent)
         => load DubboConfigBeanInitializer bean
               load dubbo config beans
               init reference beans
         => initialize dubbo bootstrap
   =>AbstractApplicationContext#finishBeanFactoryInitialization()
      => beanFactory.preInstantiateSingletons()
            load other non-lazy singleton beans, including service impl beans, ReferenceBeans, ServiceBeans 
   =>AbstractApplicationContext#finishRefresh()
      => publish ContextRefreshedEvent
         => start dubbo bootstrap

The goal is to initialize dubbo config beans safely after all BeanPostProcessors are registered.

Previously they are initialized in the DubboConfigInitializationPostProcessor.postProcessBeforeInitialization() method. It may fail due to some dubbo config bean being created recursively in java config.
The following example demonstrates the failure of init ApplicationConfig by DubboConfigInitializationPostProcessor:

@Configuration
public class ProviderConfiguration {
    @Bean("dubbo-demo-application")
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("dubbo-demo-application");
        return applicationConfig;
    }
   ...
}
beanFactory.preInstantiateSingletons() 
  > getBean(providerConfiguration)  << create providerConfiguration bean first time
  > DubboConfigInitializationPostProcessor.postProcessBeforeInitialization() 
  > DubboConfigInitializationPostProcessor.prepareDubboConfigBeans()
  > getBeansOfType(ApplicationConfig.class)  
  > getBean(dubbo-demo-application)  << create application config bean
  > instantiateUsingFactoryMethod 
  > getBean(providerConfiguration)  << create factoryBean providerConfiguration bean recursively here
  > BeanCurrentlyInCreationException

Now by processing the DubboAnnotationInitedEvent event, it is actually executed after AbstractApplicationContext#registerBeanPostProcessors() and before the AbstractApplicationContext.finishBeanFactoryInitialization() method. At this time, other beans have not yet begun to be created. This is a good time to process dubbo config beans.

AbstractApplicationContext.registerListeners()
  > DubboBootstrapApplicationListener.onApplicationEvent()
  > getBean(dubboConfigBeanInitializer)
  > DubboConfigBeanInitializer.init()
  > loadConfigBeansOfType(ApplicationConfig.class)
  > getBean(dubbo-demo-application)  << create application config bean 
  > instantiateUsingFactoryMethod
  > getBean(providerConfiguration)  << create factoryBean providerConfiguration here 
  > instantiate(dubbo-demo-application) 

Brief changelog

  • Rename DubboConfigInitializationPostProcessor to DubboConfigBeanInitializer.
  • Add DubboAnnotationInitedEvent event for initializing.
  • Load config beans by name is more reliable.
  • Add DubboConfigBeanInitializerTest
  • Remove @PostConstruct method from AbstractConfig, register config beans in DubboConfigBeanInitializer, avoid relying on javax.annotation-api.

Verifying this change

Fix issue : the xml configuration is not registered when missing javax.annotation-api: #8213

Checklist

  • Make sure there is a GitHub_issue field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
  • Each commit in the pull request should have a meaningful subject line and body.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
  • Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in dubbo samples project.
  • Add some description to dubbo-website project if you are requesting to add a feature.
  • GitHub Actions works fine on your own branch.
  • If this contribution is large, please follow the Software Donation Guide.

@AlbumenJ
Copy link
Member

Please fix ut

@codecov-commenter
Copy link

codecov-commenter commented Jul 6, 2021

Codecov Report

Merging #8168 (67a4e92) into 3.0 (940c7da) will increase coverage by 0.04%.
The diff coverage is 94.00%.

Impacted file tree graph

@@             Coverage Diff              @@
##                3.0    #8168      +/-   ##
============================================
+ Coverage     63.95%   63.99%   +0.04%     
  Complexity      311      311              
============================================
  Files          1072     1073       +1     
  Lines         45218    45229      +11     
  Branches       6810     6813       +3     
============================================
+ Hits          28918    28945      +27     
+ Misses        13079    13063      -16     
  Partials       3221     3221              
Impacted Files Coverage Δ
...n/java/org/apache/dubbo/config/AbstractConfig.java 80.70% <ø> (-0.12%) ⬇️
...ain/java/org/apache/dubbo/config/MethodConfig.java 87.87% <ø> (-0.10%) ⬇️
.../org/apache/dubbo/config/spring/ReferenceBean.java 94.36% <ø> (ø)
...fig/spring/context/DubboConfigBeanInitializer.java 90.90% <90.90%> (ø)
...notation/ReferenceAnnotationBeanPostProcessor.java 89.69% <100.00%> (+0.05%) ⬆️
...ing/context/DubboBootstrapApplicationListener.java 81.08% <100.00%> (+9.08%) ⬆️
...ring/context/event/DubboAnnotationInitedEvent.java 100.00% <100.00%> (ø)
.../config/spring/reference/ReferenceBeanManager.java 83.92% <100.00%> (ø)
...pache/dubbo/config/spring/util/DubboBeanUtils.java 85.36% <100.00%> (ø)
...in/java/org/apache/dubbo/common/utils/JVMUtil.java 81.13% <0.00%> (-11.33%) ⬇️
... and 19 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 940c7da...67a4e92. Read the comment docs.

@kylixs kylixs changed the title [3.0] Improve dubbo bootstrap initialization [3.0] Improve dubbo config beans and bootstrap initialization Jul 9, 2021
@AlbumenJ AlbumenJ merged commit e321324 into apache:3.0 Jul 10, 2021
@kylixs kylixs deleted the 3.0-initialize-dubbo-0629 branch October 23, 2021 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants