写作目的
Dubbo作为RPC中的经典落地实践,作为阿里内部目前还是大规模使用的基础框架,作为CRUD的底层。无论从什么角度来看简单的阅读一下Dubbo的源码还是有必要的。
前提:要了解Bean的生命周期
源码下载
gitee源码下载
源码分析
开启Dubbo引入了什么
以SpringBoot整合Dubbo为例,我们会使用以下注解
@EnableDubbo
该注解是符合注解,引入了一堆用于Spring提供的拓展点用于加载Dubbo的拓展点类,类的作用可以看上面的图。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
}
服务提供者怎么暴露
一般我们对外暴露服务会使用DubboService注解
@DubboService(interfaceClass = CreativeCommandService.class)
public class CreativeServiceImpl implements CreativeCommandService {
@Override
public Integer creativeCreative(CreativeDTO creativeDTO) {
System.out.println(LocalDateTime.now().toString());
return 9527;
}
}
那么注解是被谁使用被谁拦截(对比Autowired)呢?
@DubboService(interfaceClass = CreativeCommandService.class)
在上面中提到了ServiceAnnotationPostProcessor(运行时机见上图)。
首先我们是知道Spring是有办法拿到有注解的DubboService的用户自定义的class的,然后重新定义一个拓展的Dubbo自定义的class。这个class就是org.apache.dubbo.config.spring.ServiceBean
ServiceBean的生命周期中做了什么
首先我们可以看一下这个类继承了哪些接口
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean,
ApplicationContextAware, BeanNameAware, ApplicationEventPublisherAware {
//省略
}
继承了InitializingBean接口,把服务添加到某个地方,用于后续的批量发布。
@Override
public void afterPropertiesSet() throws Exception {
if (StringUtils.isEmpty(getPath())) {
if (StringUtils.isNotEmpty(getInterface())) {
setPath(getInterface());
}
}
//register service bean
ModuleModel moduleModel = DubboBeanUtils.getModuleModel(applicationContext);
//把需要暴露的服务加到某一个地方
//把需要暴露的服务加到某一个地方
//把需要暴露的服务加到某一个地方
moduleModel.getConfigManager().addService(this);
moduleModel.getDeployer().setPending();
}
什么时候发布
上文有提到DubboDeployApplicationListener,这个类会在IOC容器加载完毕后被通知到。最后调用ServiceBean#exported方法
当然具体的暴露细节可以在详细看,但是整体的思路还是很清晰。
总结
顶层设计,宏观思维。带着目的去看源码,看设计思路,不要陷入细节。
拓展点的设计。一个好的框架是会使用者足够的拓展点使其二开框架。