Dubbo构造ServiceBean过程

Dubbo源码分析
1 注册Provider
1.1 构造ServiceBean
ServiceBean继承与ServiceConfig,构造完成,并注册后。在触发ServiceBean的onApplicationEvent事件后,进行dubbo意义上的provider注册zookeeper。一个ServiceBean就对应一个@Service的注解,注解的属性其实和在配置文件中是一致的。所以说,我们是可以做到每一个微服务接口,注册到不同的注册中心的。当然一般不会这么干。
首先dubbo使用ServiceAnnotationBeanPostProcessor实现spring的BeanDefinitionRegistryPostProcessor接口。
这个接口是用来注册在配置文件或者注解中配置的javaBean.
BeanDefinitionRegistryPostProcessor提供了让我们对BeanDefinition进行自定义注册的方法,如果Spring中的默认配置方式不能满足你的要求,就可以通过实现BeanDefinitionRegistryPostProcessor接口来进行扩展。(详情:http://rason.me/2016/12/16/BeanDefinitionRegistryPostProcessor/)

首先看下这个接口的方法:
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

 这个方法实现后,spring传入BeanDefinitionRegistry(Bean 定义注册),然后并调用方法。只需要在其中写注册的bean的业务。在这里就要注册dubbo需要的什么protocol,service,provide等参数。
 再看看实现:

private void registerServiceBeans(Set packagesToScan, BeanDefinitionRegistry registry) {

DubboClassPathBeanDefinitionScanner scanner =
        new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);

BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);

scanner.setBeanNameGenerator(beanNameGenerator);

scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));

for (String packageToScan : packagesToScan) {

    // Registers @Service Bean first
    scanner.scan(packageToScan);

    // Finds all BeanDefinitionHolders of @Service whether @ComponentScan scans or not.
    Set<BeanDefinitionHolder> beanDefinitionHolders =
            findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);

    if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {

        for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
            registerServiceBean(beanDefinitionHolder, registry, scanner);
        }

通过DubboClassPathBeanDefinitionScanner进行扫描,配置注解的service类并注册他们,把scanner传递下去。然后从中过滤出带有@service注解的bean包装成BeanDefinitionHolder传递给registerServiceBean(beanDefinitionHolder, registry, scanner)方法。然后看看registerServiceBean做了什么。

private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,DubboClassPathBeanDefinitionScanner scanner) {

Class<?> beanClass = resolveClass(beanDefinitionHolder);

Service service = findAnnotation(beanClass, Service.class);

Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service);

String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();

AbstractBeanDefinition serviceBeanDefinition =
        buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);

// ServiceBean Bean name
String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);

if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
    registry.registerBeanDefinition(beanName, serviceBeanDefinition);

    if (logger.isInfoEnabled()) {
        logger.warn("The BeanDefinition[" + serviceBeanDefinition +
                "] of ServiceBean has been registered with name : " + beanName);
    }

} else {

通过上一步BeanDefinitionHolder解析出字节码对象,接口的字节码,bean的名字包装为AbstractBeanDefinition给BeanDefinitionRegistry(spring)进行注册。先来看看buildServiceBeanDefinition是怎么构造AbstractBeanDefinition的。
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);

AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();

MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();

String[] ignoreAttributeNames = of(“provider”, “monitor”, “application”, “module”, “registry”, “protocol”, “interface”);

propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(service, environment, ignoreAttributeNames));

// References “ref” property to annotated-@Service Bean
addPropertyReference(builder, “ref”, annotatedServiceBeanName);
// Set interface
builder.addPropertyValue(“interface”, interfaceClass.getName());

/**
* Add {@link org.apache.dubbo.config.ProviderConfig} Bean reference
*/
String providerConfigBeanName = service.provider();
if (StringUtils.hasText(providerConfigBeanName)) {
addPropertyReference(builder, “provider”, providerConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.MonitorConfig} Bean reference
*/
String monitorConfigBeanName = service.monitor();
if (StringUtils.hasText(monitorConfigBeanName)) {
addPropertyReference(builder, “monitor”, monitorConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.ApplicationConfig} Bean reference
*/
String applicationConfigBeanName = service.application();
if (StringUtils.hasText(applicationConfigBeanName)) {
addPropertyReference(builder, “application”, applicationConfigBeanName);
}

/**
* Add {@link org.apache.dubbo.config.ModuleConfig} Bean reference
*/
String moduleConfigBeanName = service.module();
if (StringUtils.hasText(moduleConfigBeanName)) {
addPropertyReference(builder, “module”, moduleConfigBeanName);
}
这里就是添加@Service注解的属性引用。源码中标记的Add Bean reference很多,未展示完。然后我跳回到上一步的registry.registerBeanDefinition去看看。他就是告诉spring我注册了这样一个javaBean。这就是注册了一个提供者的过程。
rootBeanDefinition(ServiceBean.class);这段代码告诉我们这BeanDefinition是以ServiceBean.class为根的,所以其实就是在构造ServiceBean.

1.2 注册Provider
上一步构造了ServiceBean即一个Provider,然后进行注册。
首先ServiceBean是监听了ApplicationListener事件,当发生着个事件时,ServiceBean就会调父类的ServiceConfig的export方法进行注册。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值