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ù)。