<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近讀完了Spring的IOC部分的原始碼,受益匪淺,這篇文章講解一下MyBatis是如何做到與Spring整合的。MyBatis是如何做到干擾Spring的生命週期,把Mapper一個個的註冊到Spring容器中的將在這裡揭祕。
因為閱讀過Spring原始碼後對他有了一定的認識,這裡可以簡單盲猜一下,使用的是什麼方式,在上一篇文章揭祕Autowired註解中有介紹到。我們只是向xml中寫入了一行<context:annotation-config/>
設定。Spring就像BeanFatory中寫入了很多的BeanPostProcessor,這裡我覺得采用的功能類似。
通過定義spring.handlers檔案。然後mybatis定義各種處理標籤的Handler和Paser。隨後通過讀取組態檔中的mappers標籤,去像register中註冊BeanDefinition,這是其一。
第二種方法就是類似AutowiredAnnotationBeanPostProcessor的實現方式,通過Xml註冊一個Bean,這個Bean繼承自MergedBeanDefinitionPostProcessor,由於繼承自MegedBeanDefinitionPostProcessor所以他會優先Bean執行,在此時可以像Bean工廠中新增BeanDefinition。
其實我們的目標很明確,只要我們能在Spring呼叫InitiazionBean方法之前去把mapper的BeanDefinition新增進Spring容器,都可以實現當前的目的。
那麼接下來我們就看看MyBatis本身究竟是如何實現的吧。
原始碼地址:MyBatis整合Spring有兩種方式,第一種是通過Xml,第二種是通過Mapper介面的掃描,具體的整合方法我這裡就不演示了,直接看組態檔吧。其實就是application.xml有一點改動。
這裡搭建一個最簡單的整合方式:
通過上方的組態檔,可以看見一個設定了一個叫scannerConfigurer,這裡先去看一下這個類。
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
這個類繼承了幾個介面:
按照這樣的一個介面被執行的順序是,setBeanName -> setApplicationContext -> afterproperties -> postProcessBeanDefinitionRegistry
@Override public void setBeanName(String name) { this.beanName = name; }
這個方法很明顯不是。
@Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; }
這個方法很明顯,也不是。
@Override public void afterPropertiesSet() throws Exception { notNull(this.basePackage, "Property 'basePackage' is required"); }
這個方法是用來校驗的,判斷了basePackage是否為空,如果為空就throw Exception。
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass); if (StringUtils.hasText(lazyInitialization)) { scanner.setLazyInitialization(Boolean.valueOf(lazyInitialization)); } if (StringUtils.hasText(defaultScope)) { scanner.setDefaultScope(defaultScope); } scanner.registerFilters(); scanner.scan( StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); }
那這裡就很明顯了,這裡建立ClassPathMapperScanner。隨後對scanner的一些設定做了一些設定。
然後就呼叫了registerFilters方法,字面意思也就是註冊過濾器,這裡就跳過吧,無非是設定一些屬性,然後在後面解析的時候判斷過濾條件,在迴圈時continue。
主要是scan方法這裡要詳細看一下:
public int scan(String... basePackages) { int beanCountAtScanStart = this.registry.getBeanDefinitionCount(); this.doScan(basePackages); if (this.includeAnnotationConfig) { AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } return this.registry.getBeanDefinitionCount() - beanCountAtScanStart; }
這裡這個掃描類其實是Spring中的類,ClassPathBeanDefinitionScanner,當中的scan方法。所以這裡可能會有點眼熟,類似於建立Bean時,先獲取一下建立之前的Bean總數,然後再獲取建立之後的Bean總數,返回時減一下就知道這次建立了多少。
其實到這裡呢,我們就算是結束了,因為後續的包掃描,在嚴格意義上來講是Spring來實現的,我後續開篇文章來講解這個東西。
這裡總結一下,正如我猜想的一樣,myBatis只要在finishBeanFactoryInitialization方法之前,把Mapper的BeanDefinition塞進Spring容器中,在最後的finishBeanFactoryInitialization方法,Spring自然就會根據BeanDefinition去建立Bean了。
這裡使用的方法是,註冊一個BeanFactoryPostProcessor,所以這個方法會在finishBeanFactoryInitialization方法之前執行,所以這裡是成功的。
到此這篇關於Spring和Mybatis整合的原理詳解的文章就介紹到這了,更多相關Spring和Mybatis整合內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45