javascript
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
為什么80%的碼農都做不了架構師?>>> ??
? ? ? 由于不想在xml里面重復繁瑣的配置bean,所以使用MapperScannerConfigurer來掃描包自動生成實例交給spring管理。但是卻發現取不到PropertyPlaceholderConfigurer里面的值導致初始化datasource失敗。
? ? 網上查閱發現只要修改SqlSessionFactoryBean的id不為sqlSessionFactory就行,說如果取名sqlSessionFactory就會觸發dataSource提前初始化,但是為什么會提前,并沒有相關解釋。
? ? ?現狀是datasource里面的配置沒有替換掉所以初始化失敗,所以我們要先看看配置是啥時候被替換的 。我們先看看spring初始化的過程(AbstractApplicationContext):
// Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. 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();? ? ? ?再來看看這幾個類的關系:
//MapperScannerConfigurer實現了BeanDefinitionRegistryPostProcessor public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor;//PropertyPlaceholderConfigurer實現了BeanFactoryPostProcessor public class PropertyPlaceholderConfigurer extends PlaceholderConfigurerSupport; public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer; public abstract class PropertyResourceConfigurer implements BeanFactoryPostProcessor;public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor;? ? ? ?那我們需要來看看invokeBeanFactoryPostProcessors(beanFactory),難道是先替換的屬性值,再注冊的BeanDefinition?
//other codes... invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); //other codes... invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);? ? ? ?顯然不可能是順序問題,那在看看報錯信息,從autowiredByName出現問題。
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:1244) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1194) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]... 39 common frames omitted protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);//propertyNames為bean可能需要注入的屬性//在MapperScannerConfigurer中,有sqlSessionFactory,nameGenerator等for (String propertyName : propertyNames) {//重點來了,如果SqlSessionFactoryBean取名sqlSessionFactory,那么容器中將包含這個bean的定義//那么SqlSessionFactoryBean將會初始化,而如果SqlSessionFactoryBean里面的Datasource也取名datasource//那么SqlSessionFactoryBean初始化也會觸發Datasource出事化,而此時還沒走到配置值替換這個階段if (containsBean(propertyName)) {Object bean = getBean(propertyName);pvs.add(propertyName, bean);registerDependentBean(propertyName, beanName);else {}}}? ? ? ? ?所以解決方案挺多的,把autowired by name去掉,SqlSessionFactoryBean不取名sqlSessionFactory,Datasource不取名datasource。
轉載于:https://my.oschina.net/chener/blog/1617384
總結
以上是生活随笔為你收集整理的Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快手幽默评论语 快手评论炸评句子115个
- 下一篇: gradle idea java ssm