程序员

Dubbo系列1-初始化(一)

2018-08-24  本文已影响0人  梦孤

在2.5.4版本中,我们通常使用以下方式启动dubbo应用

public static void main(String[] args) {
    com.alibaba.dubbo.container.Main.main(args);
}

深入这个方法,其实核心的代码是这一段

public void start() {
    String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
    if (configPath == null || configPath.length() == 0) {
        configPath = DEFAULT_SPRING_CONFIG;
    }
    context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"), false);
    context.addApplicationListener(new DubboApplicationListener());
    context.registerShutdownHook();
    context.refresh();
    context.start();
}

可以看到,其实还启动了spring的ClassPathXmlApplicationContext,并添加了一个DubboApplicationListener。更细的内容先放放,再看看在2.5.8版本后的基于annotation的启动方式:

public static void main(String[] args) throws Exception {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class);
    context.start();
    System.in.read();
}

这里除了换成创建AnnotationConfigApplicationContext意外,特别的就是这个ProviderConfiguration

@Configuration
@EnableDubbo(scanBasePackages = "com.alibaba.dubbo.samples.impl")
@PropertySource("classpath:/spring/dubbo-provider.properties")
public class ProviderConfiguration {
}

是不是和sprinBoot的风格很像,相比之前的xml配置方式,是不是清爽了很多?
下面顺便也把provider中的service以及consumer中的reference一并贴一下,方便大家阅读:

@Component("annotatedConsumer")
public class GreetingServiceConsumer {

    @Reference
    private GreetingService greetingService;

    public String doSayHello(String name) {
        return greetingService.sayHello(name);
    }
}
@Service
public class AnnotatedGreetingService implements GreetingService {
    public String sayHello(String name) {
        System.out.println("greeting service received: " + name);
        return "hello, " + name;
    }
}

除了@Service和@Reference两个Dubbo的标注,就没有其他框架层面的代码了,大大减少我们配置的工作量。
回到我们的主题,知道了程序启动的入口,也知道其实都是通过spring容器来加载dubbo的Service的,那么Service是怎么加载并初始化的呢,这里分成两个阶段来介绍,一个是Service定义的加载;另一个是Service对象的实例化;

Service定义的加载

先来看看这个类

/**
 * {@link Service} Annotation
 * {@link BeanDefinitionRegistryPostProcessor Bean Definition Registry Post Processor}
 *
 * @since 2.5.8
 */
public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware,
        ResourceLoaderAware, BeanClassLoaderAware {
...
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);

        if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
            // 核心方法是这个
            registerServiceBeans(resolvedPackagesToScan, registry);
        } else {
            if (logger.isWarnEnabled()) {
                logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!");
            }
        }

    }
    /**
     * 注册被 {@link Service}标注的类的Bean(此Bean是Service类的定义)
     *
     * @param packagesToScan The base packages to scan
     * @param registry       {@link BeanDefinitionRegistry}
     */
    private void registerServiceBeans(Set<String> 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) {
                    // 解析生成Service的定义Bean,并注册到spring容器中
                    registerServiceBean(beanDefinitionHolder, registry, scanner);
                }
            } 

        }

    }
...
}
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();
        // 解析Service类的注解,创建RootBeanDefinition对象,对象的beanClass属性值为ServiceBean
        AbstractBeanDefinition serviceBeanDefinition =
                buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);

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

        if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
            // 注册ServcieBean到spring容器中
            registry.registerBeanDefinition(beanName, serviceBeanDefinition);
...
}

未完待续...

上一篇 下一篇

猜你喜欢

热点阅读