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注解的方法汹桦,注冊(cè)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在這里主要用于反注冊(cè)服務(wù)(server端)和刪除對(duì)服務(wù)(客戶端)引用住册。
流程比較簡(jiǎn)單。
這里涉及一個(gè)問題瓮具,Motan優(yōu)雅關(guān)機(jī) 中提到荧飞,kill進(jìn)程時(shí),Motan服務(wù)端也會(huì)反注冊(cè)服務(wù)名党,當(dāng)時(shí)只提到是spring發(fā)起的叹阔。實(shí)際上是spring容器注冊(cè)了關(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方法传睹,
// 所以這樣可以反注冊(cè)服務(wù)耳幢。