【學習】從spring-mybatis看如何自定義基於動態代理的結合spring的框架

從spring-mybatis看如何自定義基於動態代理的結合spring的框架

寫在前面

最近同事做了一個mybatis分享,涉及到很多東西,對其中mybatis-spring比較感興趣,所以深入瞭解下,
這對以後其他任何基於接口動態代理的功能模塊能夠更加快速的瞭解和學習。

入口

入口是在xml中配置的org.mybatis.spring.mapper.MapperScannerConfigurer,爲什麼是他,來看看他的定義

class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {}

其他接口沒啥實際實現,這裏重點看下實現BeanDefinitionRegistryPostProcessor(它是BeanFactoryPostProcessor的一個實現類,
執行是在org.springframework.context.support.AbstractApplicationContext#refresh 觸發的,具體請看下面的
spring bean 生命週期)的postProcessBeanDefinitionRegistry()方法,
它內部是調用ClassPathMapperScanner#scan,分兩步:

  1. 先調用父類ClassPathBeanDefinitionScanner的doScan方法,返回包下面符合條件的BeanDefinitionHolder,
  2. 然後將在xml中配置的屬性都添加到bean的屬性中,需要特別注意的屬性:
    1. definition.setBeanClass(MapperFactoryBean.class) 表示通過MapperFactoryBean獲取mapper的動態代理,
    2. 通過definition.getPropertyValues().add sqlSessionFactory 和 sqlSessionTemplate屬性,表示在實例化代理之前,
      會先實例化SqlSessionFactory 或者 sqlSessionTemplate

這一步就已經完成BeanDefinition註冊,真正初始化bean是在org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization中完成的,
這裏不會細看,裏面內容很多,需要看的小夥伴可以看看finishBeanFactoryInitialization

bean實例化

上面也說了 在實例化mapper代理之前,會先實例化依賴的屬性(sqlSessionFactory 和 sqlSessionTemplate),
在項目中我們常配置的是sqlSessionFactory,這裏看下SqlSessionFactoryBean,主要的邏輯在org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory 中,
它會解析xml配置,實例化Configuration,並被SqlSessionFactory持有。

SqlSessionFactoryBean實例化之後,通過反射(org.mybatis.spring.support.SqlSessionDaoSupport#setSqlSessionFactory)
把屬性設置到mapperFactoryBean中,這一步其實是構建一個SqlSession,屬性設置完成後,調用getObject返回實例,這樣就完成了一個Mapper代理的加載。

public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
}

這裏的sqlSession是mybatis-spring自定義的SqlSessionTemplate,getMapper調用的是org.apache.ibatis.session.Configuration#getMapper,
這走到了mybatis的部分,偏離了這篇的主題,有興趣可以自行看看,就是繞繞繞,返回一個Mapper的jdk動態代理。

使用接口動態代理的實現

公司實現的feign

實現的思路其實是一樣的,都是先註冊bean(這裏用的ImportBeanDefinitionRegistrar),通過factoryBean.getObject獲取,在這裏面再動態代理自己需要的邏輯

spring aop的實現

spring aop邏輯實現不一樣,他不會先去註冊需要加強的bean,或者說他只會針對已有的bean進行加強,
加強postProcessAfterInitialization邏輯在AspectJAwareAdvisorAutoProxyCreator中,它是BeanPostProccessor的實現類。
spring aop這篇寫的很詳細,可以看看。

延伸&引用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章