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

mybatis-spring-2.0.5 MapperScannerConfigurer 导致brcc多次加载 #12

Closed
ghzengqy568 opened this issue Mar 3, 2021 · 1 comment
Closed
Projects

Comments

@ghzengqy568
Copy link
Collaborator

现象:
引入mybatis-spring-boot-starter 2.1.3 (对应mybatis-spring 2.0.5)后, 在多数据源情况下sdk多次加载brcc配置。
问题分析:
项目中多数据源情况下, 通过@MapperScan指定扫描不同的package和sqlSessionFactory, @MapperScan -> @import(MapperScannerRegistrar.class) -> MapperScannerConfigurer
MapperScannerConfigurer 实现了BeanDefinitionRegistryPostProcessor接口, 在配置processPropertyPlaceHolders为true的情况下会调用processPropertyPlaceHolders()方法
`
private void processPropertyPlaceHolders() {
// 获取到brcc的ConfigCenterPropertyPlaceholderConfigurer
Map<String, PropertyResourceConfigurer> prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class,
false, false);

if (!prcs.isEmpty() && applicationContext instanceof ConfigurableApplicationContext) {
  BeanDefinition mapperScannerBean = ((ConfigurableApplicationContext) applicationContext).getBeanFactory()
      .getBeanDefinition(beanName);

  // PropertyResourceConfigurer does not expose any methods to explicitly perform
  // property placeholder substitution. Instead, create a BeanFactory that just
  // contains this mapper scanner and post process the factory.
  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
  factory.registerBeanDefinition(beanName, mapperScannerBean);

  for (PropertyResourceConfigurer prc : prcs.values()) {
    // 主动调用brcc替换mapperScannerBean中的属性
    prc.postProcessBeanFactory(factory);
  }

  PropertyValues values = mapperScannerBean.getPropertyValues();

  this.basePackage = updatePropertyValue("basePackage", values);
  this.sqlSessionFactoryBeanName = updatePropertyValue("sqlSessionFactoryBeanName", values);
  this.sqlSessionTemplateBeanName = updatePropertyValue("sqlSessionTemplateBeanName", values);
  this.lazyInitialization = updatePropertyValue("lazyInitialization", values);
}
this.basePackage = Optional.ofNullable(this.basePackage).map(getEnvironment()::resolvePlaceholders).orElse(null);
this.sqlSessionFactoryBeanName = Optional.ofNullable(this.sqlSessionFactoryBeanName)
    .map(getEnvironment()::resolvePlaceholders).orElse(null);
this.sqlSessionTemplateBeanName = Optional.ofNullable(this.sqlSessionTemplateBeanName)
    .map(getEnvironment()::resolvePlaceholders).orElse(null);
this.lazyInitialization = Optional.ofNullable(this.lazyInitialization).map(getEnvironment()::resolvePlaceholders)
    .orElse(null);

}

`
这样导致了brcc多次远程调用

@ghzengqy568 ghzengqy568 added this to In progress in 1.0.3 Mar 3, 2021
@ghzengqy568 ghzengqy568 moved this from In progress to Done in 1.0.3 Mar 3, 2021
@ghzengqy568
Copy link
Collaborator Author

ghzengqy568 commented Mar 3, 2021

现象:
引入mybatis-spring-boot-starter 2.1.3 (对应mybatis-spring 2.0.5)后, 在多数据源情况下sdk多次加载brcc配置。
问题分析:
项目中多数据源情况下, 通过@MapperScan指定扫描不同的package和sqlSessionFactory, @MapperScan -> @import(MapperScannerRegistrar.class) -> MapperScannerConfigurer
MapperScannerConfigurer 实现了BeanDefinitionRegistryPostProcessor接口, 在配置processPropertyPlaceHolders为true的情况下会调用processPropertyPlaceHolders()方法
`
private void processPropertyPlaceHolders() {
// 获取到brcc的ConfigCenterPropertyPlaceholderConfigurer
Map<String, PropertyResourceConfigurer> prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class,
false, false);

if (!prcs.isEmpty() && applicationContext instanceof ConfigurableApplicationContext) {
  BeanDefinition mapperScannerBean = ((ConfigurableApplicationContext) applicationContext).getBeanFactory()
      .getBeanDefinition(beanName);

  // PropertyResourceConfigurer does not expose any methods to explicitly perform
  // property placeholder substitution. Instead, create a BeanFactory that just
  // contains this mapper scanner and post process the factory.
  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
  factory.registerBeanDefinition(beanName, mapperScannerBean);

  for (PropertyResourceConfigurer prc : prcs.values()) {
    // 主动调用brcc替换mapperScannerBean中的属性
    prc.postProcessBeanFactory(factory);
  }

  PropertyValues values = mapperScannerBean.getPropertyValues();

  this.basePackage = updatePropertyValue("basePackage", values);
  this.sqlSessionFactoryBeanName = updatePropertyValue("sqlSessionFactoryBeanName", values);
  this.sqlSessionTemplateBeanName = updatePropertyValue("sqlSessionTemplateBeanName", values);
  this.lazyInitialization = updatePropertyValue("lazyInitialization", values);
}
this.basePackage = Optional.ofNullable(this.basePackage).map(getEnvironment()::resolvePlaceholders).orElse(null);
this.sqlSessionFactoryBeanName = Optional.ofNullable(this.sqlSessionFactoryBeanName)
    .map(getEnvironment()::resolvePlaceholders).orElse(null);
this.sqlSessionTemplateBeanName = Optional.ofNullable(this.sqlSessionTemplateBeanName)
    .map(getEnvironment()::resolvePlaceholders).orElse(null);
this.lazyInitialization = Optional.ofNullable(this.lazyInitialization).map(getEnvironment()::resolvePlaceholders)
    .orElse(null);

}

`
这样导致了brcc多次远程调用

sdk中添加加载标志,当第一次加载成功后加载标志设置为true,后面加不再加载

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
1.0.3
Done
Development

No branches or pull requests

1 participant