1.先了解下dubbo的常用配置
例子
例子
例子
例子
例子
例子
例子
例子
还有其他一些属性,可以去dubbo官网查看
http://dubbo.apache.org/books/dubbo-user-book/references/xml/introduction.html
2.了解下spring是怎么识别dubbo的
后面会结合官网提供的暴露服务时序图来对dubbo服务进行一个讲解,今天先讲一个spring是怎么实现跟dubbo结合的,dubbo是什么时候触发export方法然后暴露服务的。
基于tomcat来分析dubbo的暴露服务
启动tomcat,在spring 容器启动时,会读取dubbo的配置文件,dubbo的配置如下
在spring加载dubbo配置文件前,先简单了解下spring的bean初始化机制:Spring的InitializingBean接口有很好的用处,位于spring beans中,它只提供一个方法afterPropertiesSet(),当你实现了该方法后,spring就会对你提供框架级的支持:当你通过sring容器生产出实现了该接口的类的实例后,它就会调用afterPropertiesSet方法,通过这个方法,你可以检查你的bean是否正确地被初始化了.当然,你也可以用init-method方法.这两种方式可以同时使用,调用的顺序为init-method后调用。
Spring读取配置文件,关键是dubbo:service标签,每个dubbo:service标签都对应一个ServiceBean实例。
来看下ServiceBean.java.这个类的定义
public class ServiceBean
这里有个关键地方:ApplicationContextAware和InitializingBean以及ApplicationListener(注意:下面三个步骤是在容器初始化的时候是按顺序来的)
1.实现了ApplicationContextAware类的setApplicationContext方法。把spring的上下文applicationContext赋给当前类中的变量,同时维护到dubbo中,通过反射调用AbstractApplicationContext.addApplicationListener方法,把当前servicebean对象作为listener添加到abstractapplicationContext中,并标记supportedApplicationListener为true。
2.ServiceBean实现了Spring提供的接口InitializingBean。当在完成Bean初始化和注入的时候程序会自动执行InitializingBean接口中的afterPropertiesSet方法(配置了几个dubbo:service,就会执行几次改方法,因为初始化与之匹配的servicebean)。在这个方法里面会对provider、application、module、registries、moniter、protocols、path等进行初始化。
如果没有设置延迟加载,则不会执行export()
if (! isDelay()) {
export();
}
也就是说并没有在此时进行服务暴漏。
3.实现了ApplicationListener接口的onApplicationEvent方法。ApplicationContext在运行期会自动检测到所有实现了ApplicationListener的bean对象,并将其作为事件接收对象,由此可知初始化的servicebean全部作为事件接收对象,当ApplicationContext的publishEvent方法被触发时,每个实现了ApplicationListener接口的bean都会收到ApplicationEvent对象,每个ApplicationListener可根据事件类型只接收处理自己感兴趣的事件,通过查看service源码,
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
可知每个servicebean对ContextRefreshedEvent感兴趣,当有ContextRefreshedEvent事件发生时,会进行export(),export操作就是dubbo开始暴露服务的入口。
关于ContextRefreshedEvent是何时触发的,由谁触发的来介绍下:在Spring中,ApplicationContext的子类AbstractApplicationContext的refresh()是构建Bean的入口点,spring在加载bean的时候,就会执行ConfigurableApplicationContext的refresh方法,看下refresh方法的实现:
finishRefresh的方法如下:
由上可知,当spring加载完一个bean的时候就会publishContextRefreshedEvent事件,而dubbo的servicebean监听了该事件,所以当该类型事件发生时,sevicebean会触发onApplicationEvent(ContextRefreshedEvent event),然后就会调用export方法了,dubbo时序图中的第一步找到了。