Motan spring-boot 啟動(dòng)分析

Motan spring-boot啟動(dòng)實(shí)際上是Motan注解方式的啟動(dòng)流程,入口類為motan-springsupport中的AnnotationBean

@Bean
public AnnotationBean motanAnnotationBean() {
    AnnotationBean motanAnnotationBean = new AnnotationBean();
    motanAnnotationBean.setPackage("com.weibo.motan.demo.server");
    return motanAnnotationBean;
}

這涉及springboot的加載流程,主入口:AbstractApplicationContext類的refresh()方法。
涉及Motan初始化的調(diào)用為refresh中的下面兩個(gè)方法(處理入口類中的@Bean注解的方法,注冊AnnotationBean的實(shí)例,然后調(diào)用setBeanFactory、postProcessBeanFactory、postProcessBeforeInitialization、postProcessAfterInitialization方法)

// Invoke factory processors registered as beans in the context.(調(diào)用上面的第一個(gè)方法)
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.(調(diào)用上面的后3個(gè)方法)
registerBeanPostProcessors(beanFactory);

AnnotationBean 實(shí)現(xiàn)了4個(gè)接口(這順序也是上面調(diào)用方法的順序)

  • BeanFactoryAware
    這個(gè)接口為了設(shè)置spring的BeanFactory實(shí)例
    BeanFactory:負(fù)責(zé)獲取bean,管理bean的加載,實(shí)例化,維護(hù)bean之間的依賴關(guān)系,負(fù)責(zé)bean的聲明周期等。Motan這里用來獲取Bean。

  • BeanFactoryPostProcessor
    實(shí)現(xiàn)方法:postProcessBeanFactory,當(dāng)所有的bean都加載完后但還沒有被初始化的時(shí)候調(diào)用,用來覆蓋或添加屬性,或提前初始化bean。
    Motan在這里為了掃包暴露服務(wù)用,整了一大堆反射,我用new方式改了下,運(yùn)行它的Demo也沒事,不知道為啥要整反射。

// 不用反射,4行就可以了,還好理解
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((BeanDefinitionRegistry) beanFactory, true);
AnnotationTypeFilter typeFilter = new AnnotationTypeFilter(MotanService.class);
scanner.addIncludeFilter(typeFilter);
scanner.scan(annotationPackages);
  • BeanPostProcessor
    需要實(shí)現(xiàn)postProcessBeforeInitialization、postProcessAfterInitialization兩個(gè)方法,兩者都是在實(shí)例化及依賴注入完成后調(diào)用,不同的是,前者在afterPropertiesSet和init-method方法調(diào)用之前調(diào)用,后者在那兩個(gè)方法調(diào)用之后調(diào)用。
    postProcessBeforeInitialization用于處理服務(wù)引用:查找方法參數(shù)和類變量上的MotanReferer注解,存在該注解則去查找服務(wù)引用,找到并給其賦值,后續(xù)就可以使用了。
    postProcessAfterInitialization用于暴露服務(wù):查找類上的MotanService注解,找到后則查找設(shè)置各種配置項(xiàng),最后暴露服務(wù)

  • DisposableBean
    需要實(shí)現(xiàn)destroy方法,當(dāng)前bean被銷毀時(shí),spring會(huì)調(diào)用該方法。
    Motan在這里主要用于反注冊服務(wù)(server端)和刪除對服務(wù)(客戶端)引用。
    流程比較簡單。
    這里涉及一個(gè)問題,Motan優(yōu)雅關(guān)機(jī) 中提到,kill進(jìn)程時(shí),Motan服務(wù)端也會(huì)反注冊服務(wù),當(dāng)時(shí)只提到是spring發(fā)起的。實(shí)際上是spring容器注冊了關(guān)閉鉤子:

// 在AbstractApplicationContext.java中
public void registerShutdownHook() {
      if (this.shutdownHook == null) {
          // No shutdown hook registered yet.
          this.shutdownHook = new Thread() {
              @Override
                  public void run() {
                      doClose();
                  }
          };
          Runtime.getRuntime().addShutdownHook(this.shutdownHook);
       }
}
// doClose() 方法會(huì)銷毀bean,而銷毀bean時(shí)會(huì)調(diào)用所有實(shí)現(xiàn)了DisposableBean接口的類的destroy方法,
// 所以這樣可以反注冊服務(wù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容