MapperScannerConfigurer导致PlaceHolder的替换变量报错

前提

1.开启了byName自动注入
2.定义了PropertySourcesPlaceholderConfigurer,去解析配置。
3.含有id="sqlSessionFactory"的SqlSessionFactory
4.定义了MapperScannerConfigurer,在其属性sqlSessionFactory中的dataSource属性中使用了${username}${password}等。

原因

  1. MapperScannerConfigurer 是一个BeanDefinitionRegistryPostProcessor,它是BeanFactoryPostProcessor的实现类。

  2. PropertySourcesPlaceholderConfigurer是一个BeanFactoryPostProcessor的实现类。

  3. MapperScannerConfigurerPropertySourcesPlaceholderConfigurer 之前被实例化。
    3.1. 这是因为它们会在Spring的refresh->invokeBeanFactoryPostProcessors(beanFactory)被调用。 而顺序是 先注册BeanDefinitionFactoryProcessor,再注册BeanFactoryPostProcessor

  4. MapperScannerConfigurer优先实例化的时候,开启了default-autowire="byName"会连同属性sqlSessionFactory一起初始化,并造成dataSource初始化, 那么${username}被提前设置到dataSource中的username属性中,但此时PropertySourcesPlaceholderConfigurer还未生成实例,更没有替换${username},导致错误!
    4.1 开启default-autowire="byName"自动注入后,会解析出需要"sqlSessionFactory"依赖,并提前初始化。

解决

由于无法改变MapperScannerConfigurer与PropertySourcesPlaceholderConfigurer的getBean初始化顺序。
那么避免sqlSessionFactory的属性提前初始化。
1.去掉default-autowire="byName"
2.改变sqlSessionFactory的id。(未验证) (TODO)

常见报错配置




    
    
        
        
        
        
    

    
        
        
    

    
        
        
    
	

参考

https://my.oschina.net/u/161336/blog/1830816

你可能感兴趣的:(Spring源码学习,Spring)