Github地址
最近在整合mybatis-spring。
公司里面已經有一個叫做kylin-datasource的開發包,以前能夠提供master和slave2個數據源,最近更新了2.0版本,支持自動掃描mapper了(之前每寫一個mapper都要自己去配個factory)。
在畢業設計的項目里面,我也准備自己寫一個mybatis與spring整合的依賴,並且希望在這個包原有的基礎上,寫的盡量完善一些。
同時也是為了能夠更加深的去了解spring的原理。
自己建項目,將源代碼類一個個拷過來,運行的時候,還是報錯了:原先有3個datasouce,datasource\masterDatasource\slaveDatasource,所以在注入的時候找到了3個,spring不知道該怎么辦了。
只好將所有slave相關的先刪了,保證能夠訪問數據庫先再說。
中間雖然也遇到了非常多的問題,但最終還是讓一個master的依賴可用了。同時,我也對原先的代碼一頓改,改成我看的習慣的樣子。。
加載配置文件
這是今天遇到的主要問題:
使用@EnableConfigurationProperties 讓properties中的屬性自動注入到bean的屬性中,這個bean叫做DatasourceProperties。
這種方法看上去非常優雅,,我也不想舍棄。
再后面的代碼中又有用到DatasourceProperties的,里面用的是
@Autowired
private DatasourceProperties datasourceProperties;
這樣就直接可以使用了,但是也有同樣用到配置屬性的,但是卻沒有用這種方法,用的是
@Bean
Properties datasourceConf() throws Exception {
PropertiesFactoryBean factoryBean = new PropertiesFactoryBean();
factoryBean.setLocation(new ClassPathResource("datasource.properties"));
factoryBean.afterPropertiesSet();
return factoryBean.getObject();
}
...datasourceConf().getProperty("datasource.master.basePackage")..
這相當於之前的配置是通過spring來的,非常優雅;而這里又回到了解放前,通過getProperty又來了一次。
所以我就把上面貼的這個方法給去了,也改成autowired的DatasourceProperties。
但是這一改就出事了,運行的時候報了空指針,打印出來一看是DatasourceProperties沒有autowired進去。
那我就想,這個spring肯定是先先將bean給生出來,然后第二步才去autowaird,而調用這個方法生成bean的時候還沒autowired所以就報錯了。
得想個辦法讓那個properties先加載起來,然后后面的再去使用它。
為此,去查了spring生命周期相關的資料。
下面貼上
生命周期
1.圖
2.接口方法分類
Bean的完整生命周期經歷了各種方法調用,這些方法可以划分為以下幾類:
1)、Bean自身的方法 : 這個包括了Bean本身調用的方法和通過配置文件中
2)、Bean級生命周期接口方法 : 這個包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法
3)、容器級生命周期接口方法 : 這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類為“后處理器”。
4)、工廠后處理器接口方法 : 這個包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工廠后處理器 接口的方法。工廠后處理器也是容器級的。在應用上下文裝配配置文件之后立即調用。
最終的解決辦法
最后是,雖然能夠得到bean,但是這個bean不是已經被自動注入配置文件信息的那個bean。
所以不要也罷。
比較理想的辦法就是找出EnableConfigurationProperties的實現,然后把他的代碼跑一遍,這樣就生成我要的bean了。
還有一個問題:
在這個地方(AutoMapperScannerConfigurator)使用autowired會報錯,而在另外一個bean里(MasterDB)不會,這個很是奇怪。
他們的區別也只是MasterDB多實現了一個接口,然后他的類名是在DatasourceProperties之后的,不過我也試過改名字,好想沒啥影響。
最后我還是先使用了工具類來讀取properties,先讓它跑起來。等到后面再想想有沒有更好的解決方案。
下次要解決的就是配置多個datasource的問題了。