Motan spring-boot 启动分析
Motan spring-boot启动实际上是Motan注解方式的启动流程,入口类为motan-springsupport中的AnnotationBean
@Bean
public AnnotationBean motanAnnotationBean() {
AnnotationBean motanAnnotationBean = new AnnotationBean();
motanAnnotationBean.setPackage("com.weibo.motan.demo.server");
return motanAnnotationBean;
}
这涉及springboot的加载流程,主入口:AbstractApplicationContext类的refresh()方法。
涉及Motan初始化的调用为refresh中的下面两个方法(处理入口类中的@Bean注解的方法,注册AnnotationBean的实例,然后调用setBeanFactory、postProcessBeanFactory、postProcessBeforeInitialization、postProcessAfterInitialization方法)
// Invoke factory processors registered as beans in the context.(调用上面的第一个方法)
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.(调用上面的后3个方法)
registerBeanPostProcessors(beanFactory);
AnnotationBean 实现了4个接口(这顺序也是上面调用方法的顺序)
-
BeanFactoryAware
这个接口为了设置spring的BeanFactory实例
BeanFactory:负责获取bean,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期等。Motan这里用来获取Bean。 -
BeanFactoryPostProcessor
实现方法:postProcessBeanFactory,当所有的bean都加载完后但还没有被初始化的时候调用,用来覆盖或添加属性,或提前初始化bean。
Motan在这里为了扫包暴露服务用,整了一大堆反射,我用new方式改了下,运行它的Demo也没事,不知道为啥要整反射。
// 不用反射,4行就可以了,还好理解
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((BeanDefinitionRegistry) beanFactory, true);
AnnotationTypeFilter typeFilter = new AnnotationTypeFilter(MotanService.class);
scanner.addIncludeFilter(typeFilter);
scanner.scan(annotationPackages);
-
BeanPostProcessor
需要实现postProcessBeforeInitialization、postProcessAfterInitialization两个方法,两者都是在实例化及依赖注入完成后调用,不同的是,前者在afterPropertiesSet和init-method方法调用之前调用,后者在那两个方法调用之后调用。
postProcessBeforeInitialization用于处理服务引用:查找方法参数和类变量上的MotanReferer注解,存在该注解则去查找服务引用,找到并给其赋值,后续就可以使用了。
postProcessAfterInitialization用于暴露服务:查找类上的MotanService注解,找到后则查找设置各种配置项,最后暴露服务 -
DisposableBean
需要实现destroy方法,当前bean被销毁时,spring会调用该方法。
Motan在这里主要用于反注册服务(server端)和删除对服务(客户端)引用。
流程比较简单。
这里涉及一个问题,Motan优雅关机 中提到,kill进程时,Motan服务端也会反注册服务,当时只提到是spring发起的。实际上是spring容器注册了关闭钩子:
// 在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() 方法会销毁bean,而销毁bean时会调用所有实现了DisposableBean接口的类的destroy方法,
// 所以这样可以反注册服务。