Dubbo与Spring集成原理

Dubbo与Spring的集成主要完成propertie文件解析处理@Service注解解析@Reference注解解析。主要是通过@EnableDubbo注解来完成的,且在该注解上指定扫描的包,完成@Service@Reference注解的扫描并且进行处理。

1
2
3
4
5
@Configuration
@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.provider")
@PropertySource("classpath:/spring/dubbo-provider.properties")
static class ProviderConfiguration {
}

@EnableDubboConfig注解用来将properties文件中的配置项转化为对应的Bean@DubboComponentScan注解用来扫描@Service@Reference注解标注的类和属性且进行相关的处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo {
@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};

@AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};

@AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
boolean multipleConfig() default true;
}

配置文件解析

@EnableDubboConfig导入了DubboConfigConfigurationRegistrar配置类,该配置类通过AnnotatedBeanDefinitionRegistryUtilsDubboConfigConfigurationSingleMultiple类注册到Spring中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig {
boolean multiple() default true;
}
public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
boolean multiple = attributes.getBoolean("multiple"); //true
registerBeans(registry, DubboConfigConfiguration.Single.class); // Single Config Bindings
if (multiple) { // 默认为true
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
}
}
}
public class DubboConfigConfiguration {
@EnableDubboConfigBindings({
@EnableDubboConfigBinding(prefix = "dubbo.application", type = ApplicationConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.module", type = ModuleConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.registry", type = RegistryConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.monitor", type = MonitorConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.provider", type = ProviderConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
@EnableDubboConfigBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
@EnableDubboConfigBinding(prefix = "dubbo.metrics", type = MetricsConfig.class)
})
public static class Single {
}
@EnableDubboConfigBindings({
@EnableDubboConfigBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.config-centers", type = ConfigCenterBean.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.metadata-reports", type = MetadataReportConfig.class, multiple = true),
@EnableDubboConfigBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true)
})
public static class Multiple {
}
}
public abstract class AnnotatedBeanDefinitionRegistryUtils {
public static void registerBeans(BeanDefinitionRegistry registry, Class<?>... annotatedClasses) {
if (ObjectUtils.isEmpty(annotatedClasses)) {
return;
}
Iterator<Class<?>> iterator = new ArrayList<>(asList(annotatedClasses)).iterator();
while (iterator.hasNext()) {
Class<?> annotatedClass = iterator.next();
if (isPresentBean(registry, annotatedClass)) {
iterator.remove();
}
}
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
// 利用Spring中的AnnotatedBeanDefinitionReader来解析annotatedClasses会解析该类上的注解,然后进行处理
reader.register(annotatedClasses);
}
}

@EnableDubboConfigBindings注解中导入了DubboConfigBindingsRegistrar配置类,该配置类中会获取并遍历注解中配置的@EnableDubboConfigBinding列表,调用DubboConfigBindingRegistrarregisterBeanDefinitions方法将生成对应的配置类注册到Spring容器中,且给每一个配置类注册一个DubboConfigBindingBeanPostProcessor后置处理器,且注册了一个NamePropertyDefaultValueDubboConfigBeanCustomizer的Bean,用来把XxConfig配置类所对应的beanName设置到name属性中去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboConfigBindingsRegistrar.class)
public @interface EnableDubboConfigBindings {
EnableDubboConfigBinding[] value();
}
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(EnableDubboConfigBindings.class)
@Import(DubboConfigBindingRegistrar.class)
public @interface EnableDubboConfigBinding {
String prefix();
Class<? extends AbstractConfig> type();
boolean multiple() default false;
}
public class DubboConfigBindingsRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBindings.class.getName()));
AnnotationAttributes[] annotationAttributes = attributes.getAnnotationArray("value"); // 拿到多个@EnableDubboConfigBinding注解
DubboConfigBindingRegistrar registrar = new DubboConfigBindingRegistrar();
registrar.setEnvironment(environment);
for (AnnotationAttributes element : annotationAttributes) {
registrar.registerBeanDefinitions(element, registry); // 逐个解析@EnableDubboConfigBinding注解
}
}
}
public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
registerBeanDefinitions(attributes, registry);

}
protected void registerBeanDefinitions(AnnotationAttributes attributes, BeanDefinitionRegistry registry) {
String prefix = environment.resolvePlaceholders(attributes.getString("prefix")); // prefix = "dubbo.application"
Class<? extends AbstractConfig> configClass = attributes.getClass("type"); // type = ApplicationConfig.class
boolean multiple = attributes.getBoolean("multiple");
registerDubboConfigBeans(prefix, configClass, multiple, registry);
}
private void registerDubboConfigBeans(String prefix, Class<? extends AbstractConfig> configClass, boolean multiple, BeanDefinitionRegistry registry) {
// 从properties文件中根据前缀拿对应的配置项,比如根据dubbo.application前缀
Map<String, Object> properties = getSubProperties(environment.getPropertySources(), prefix);
if (CollectionUtils.isEmpty(properties)) {
return; // 如果没有相关的配置项,则不需要注册BeanDefinition
}
Set<String> beanNames = multiple ? resolveMultipleBeanNames(properties) : Collections.singleton(resolveSingleBeanName(properties, configClass, registry));
for (String beanName : beanNames) {
registerDubboConfigBean(beanName, configClass, registry); // 为每个beanName,注册一个空的BeanDefinition
// 为每个bean注册一个DubboConfigBindingBeanPostProcessor的Bean后置处理器
registerDubboConfigBindingBeanPostProcessor(prefix, beanName, multiple, registry);
}
// 注册一个NamePropertyDefaultValueDubboConfigBeanCustomizer的bean,用来把某个XxConfig所对应的beanName设置到name属性中去
registerDubboConfigBeanCustomizers(registry);
}
private Set<String> resolveMultipleBeanNames(Map<String, Object> properties) {
Set<String> beanNames = new LinkedHashSet<String>();
// 比如dubbo.protocols.p1.name=dubbo的propertyName为p1.name
for (String propertyName : properties.keySet()) {
int index = propertyName.indexOf("."); // propertyName为p1.name
if (index > 0) {
String beanName = propertyName.substring(0, index); // 截取beanName名字为p1
beanNames.add(beanName);
}
}
return beanNames;
}
private void registerDubboConfigBean(String beanName, Class<? extends AbstractConfig> configClass, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = rootBeanDefinition(configClass);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
registry.registerBeanDefinition(beanName, beanDefinition); // ApplicatinoConfig对象
}
private void registerDubboConfigBindingBeanPostProcessor(String prefix, String beanName, boolean multiple, BeanDefinitionRegistry registry) {
// 为每个XxConfig的Bean对应一个DubboConfigBindingBeanPostProcessor的Bean
Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
BeanDefinitionBuilder builder = rootBeanDefinition(processorClass);
// 真实的前缀,比如dubbo.registries.r2
String actualPrefix = multiple ? normalizePrefix(prefix) + beanName : prefix;
// 添加两个构造方法参数值,所以会调用DubboConfigBindingBeanPostProcessor的两个参数的构造方法
builder.addConstructorArgValue(actualPrefix).addConstructorArgValue(beanName);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registerWithGeneratedName(beanDefinition, registry);
}
private void registerDubboConfigBeanCustomizers(BeanDefinitionRegistry registry) {
registerInfrastructureBean(registry, BEAN_NAME, NamePropertyDefaultValueDubboConfigBeanCustomizer.class);
}
}

DubboConfigBindingBeanPostProcessor是一个BeanPostProcessor,且实现了InitializingBean接口,在其afterPropertiesSet方法中会对DubboConfigBinder属性初始化,且获取到上面注册的NamePropertyDefaultValueDubboConfigBeanCustomizer对象。在postProcessBeforeInitialization方法中从properties文件中获取值,并设置到对应的Config文件对象中,然后调用NamePropertyDefaultValueDubboConfigBeanCustomizercustomize方法将beanName设置到name属性中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, InitializingBean, BeanDefinitionRegistryPostProcessor {
public void afterPropertiesSet() throws Exception {
initDubboConfigBinder(); // 创建DefaultDubboConfigBinder
initConfigBeanCustomizers();
}
private void initDubboConfigBinder() {
if (dubboConfigBinder == null) {
try {// 先从Spring容器中获取DubboConfigBinder,默认获取不到
dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
} catch (BeansException ignored) {
// Use Default implementation 生成一个默认的
dubboConfigBinder = createDubboConfigBinder(applicationContext.getEnvironment());
}
}
dubboConfigBinder.setIgnoreUnknownFields(ignoreUnknownFields);
dubboConfigBinder.setIgnoreInvalidFields(ignoreInvalidFields);
}
private void initConfigBeanCustomizers() { // 得到之前创建了的NamePropertyDefaultValueDubboConfigBeanCustomizer
Collection<DubboConfigBeanCustomizer> configBeanCustomizers = beansOfTypeIncludingAncestors(applicationContext, DubboConfigBeanCustomizer.class).values();
this.configBeanCustomizers = new ArrayList<>(configBeanCustomizers);
AnnotationAwareOrderComparator.sort(this.configBeanCustomizers);
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 每个XxConfig对应一个BeanPostProcessor,所以每个DubboConfigBindingBeanPostProcessor只处理对应的beanName
if (this.beanName.equals(beanName) && bean instanceof AbstractConfig) {
AbstractConfig dubboConfig = (AbstractConfig) bean;
bind(prefix, dubboConfig); // 从properties文件中获取值,并设置到dubboConfig对象中
customize(beanName, dubboConfig); // 设置dubboConfig对象的name属性,设置为beanName
}
return bean;
}
private void bind(String prefix, AbstractConfig dubboConfig) {
dubboConfigBinder.bind(prefix, dubboConfig);
}
private void customize(String beanName, AbstractConfig dubboConfig) {
for (DubboConfigBeanCustomizer customizer : configBeanCustomizers) {
customizer.customize(beanName, dubboConfig);
}
}
}
public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboConfigBeanCustomizer {
public void customize(String beanName, AbstractConfig dubboConfigBean) {
// 查看XxConfig中是否存在name属性
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dubboConfigBean.getClass(), PROPERTY_NAME);
if (propertyDescriptor != null) { // "name" property is present
Method getNameMethod = propertyDescriptor.getReadMethod(); // 看是否存在getName方法
if (getNameMethod == null) { // if "getName" method is absent
return;
}
Object propertyValue = ReflectionUtils.invokeMethod(getNameMethod, dubboConfigBean); // 执行getName得到值
if (propertyValue != null) { // If The return value of "getName" method is not null
return;
}
Method setNameMethod = propertyDescriptor.getWriteMethod(); // 获取setName方法
if (setNameMethod != null) { // "setName" and "getName" methods are present
if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
ReflectionUtils.invokeMethod(setNameMethod, dubboConfigBean, beanName); // 这是name属性为beanName
}
}
}
}
}

Bean扫描

@DubboComponentScan注解中导入了DubboComponentScanRegistrar配置类,该类registerBeanDefinitions方法获取@DubboComponentScan注解中配置包路径,创建扫描@Service注解的后置处理器ServiceAnnotationBeanPostProcessor以及扫描@Reference注解的后置处理器ReferenceAnnotationBeanPostProcessor且设置获取到的扫描包路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 拿到DubboComponentScan注解所定义的包路径,扫描该package下的类
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
// 注册ServiceAnnotationBeanPostProcessor后置处理器,扫描@Service注解的类生成BeanDefinition,会生成两个一个普通的bean一个ServiceBean
// 在ServiceBean中会监听ContextRefreshedEvent事件,一旦Spring启动完后,就会进行服务导出
registerServiceAnnotationBeanPostProcessor(packagesToScan, registry);
// 注册ReferenceAnnotationBeanPostProcessor,在对属性进行注入时会调用postProcessPropertyValues方法,按照@Reference注解的信息去生成一个RefrenceBean对象
registerReferenceAnnotationBeanPostProcessor(registry);
}
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(DubboComponentScan.class.getName()));
String[] basePackages = attributes.getStringArray("basePackages");
Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses");
String[] value = attributes.getStringArray("value");
Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value)); // Appends value array attributes
packagesToScan.addAll(Arrays.asList(basePackages));
for (Class<?> basePackageClass : basePackageClasses) {
packagesToScan.add(ClassUtils.getPackageName(basePackageClass));
}
if (packagesToScan.isEmpty()) {
return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName()));
}
return packagesToScan;
}
private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
// 生成一个RootBeanDefinition,对应的beanClass为ServiceAnnotationBeanPostProcessor.class
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationBeanPostProcessor.class);
// 将包路径作为在构造ServiceAnnotationBeanPostProcessor时调用构造方法时的传入参数
builder.addConstructorArgValue(packagesToScan);
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
}
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// 注册一个ReferenceAnnotationBeanPostProcessor做为bean,ReferenceAnnotationBeanPostProcessor是一个BeanPostProcessor
BeanRegistrar.registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
}

ServiceAnnotationBeanPostProcessor后置处理器主要作用是通过DubboClassPathBeanDefinitionScanner扫描被Dubbo的@Service注解标注的类,首先将这些被@Service注解标注的类注册到Spring容器中,然后解析@Service注解服务参数信息,针对原始Bean额外生成一个类型为ServiceBean名称为ServiceBean:实际类全限定名:version:group的Bean对象,且在构建ServiceBean将Spring中对应的Bean赋值ServiceBeanref属性,以及实际的接口等信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ResourceLoaderAware, BeanClassLoaderAware {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
registerServiceBeans(resolvedPackagesToScan, registry); // 扫描包,进行Bean注册
}
}
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)); // 扫描被Service注解标注的类
scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class));
for (String packageToScan : packagesToScan) {
scanner.scan(packageToScan); // 扫描Dubbo自定义的@Service注解
// 查找被@Service注解的类的BeanDefinition,无论该类是否被@ComponentScan注解标注
Set<BeanDefinitionHolder> beanDefinitionHolders = findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
registerServiceBean(beanDefinitionHolder, registry, scanner); // 扫描到BeanDefinition开始处理它
}
}
}
}
private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry, DubboClassPathBeanDefinitionScanner scanner) {
Class<?> beanClass = resolveClass(beanDefinitionHolder); // 服务实现类
Annotation service = findServiceAnnotation(beanClass); // @Service注解
/**
* The {@link AnnotationAttributes} of @Service annotation
*/
AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false); // @Service注解上的信息
Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass); // 服务实现类对应的接口
// 服务实现类对应的bean的名字,比如:demoServiceImpl
String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
// 生成一个ServiceBean
AbstractBeanDefinition serviceBeanDefinition = buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName);
String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass); // ServiceBean Bean name
if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
// 把ServiceBean注册进去,对应的beanName为ServiceBean:org.apache.dubbo.demo.DemoService
registry.registerBeanDefinition(beanName, serviceBeanDefinition);
}
}
private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation, AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass, String annotatedServiceBeanName) {
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class); // 生成一个ServiceBean对应的BeanDefinition
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", "interface", "interfaceName", "parameters");
// 把serviceAnnotation中的参数值赋值给ServiceBean的属性
propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotation, environment, ignoreAttributeNames));
// ref属性赋值为另外一个bean, 对应的就是被@Service注解的服务实现类对应的bean
addPropertyReference(builder, "ref", annotatedServiceBeanName);
builder.addPropertyValue("interface", interfaceClass.getName());
builder.addPropertyValue("parameters", convertParameters(serviceAnnotationAttributes.getStringArray("parameters")));
// 配置了methods属性,则给ServiceBean对应的methods属性赋值
List<MethodConfig> methodConfigs = convertMethodConfigs(serviceAnnotationAttributes.get("methods"));
if (!methodConfigs.isEmpty()) {
builder.addPropertyValue("methods", methodConfigs);
}
String providerConfigBeanName = serviceAnnotationAttributes.getString("provider");
if (StringUtils.hasText(providerConfigBeanName)) {
addPropertyReference(builder, "provider", providerConfigBeanName);
}
String monitorConfigBeanName = serviceAnnotationAttributes.getString("monitor");
if (StringUtils.hasText(monitorConfigBeanName)) {
addPropertyReference(builder, "monitor", monitorConfigBeanName);
}
String applicationConfigBeanName = serviceAnnotationAttributes.getString("application");
if (StringUtils.hasText(applicationConfigBeanName)) {
addPropertyReference(builder, "application", applicationConfigBeanName);
}
String moduleConfigBeanName = serviceAnnotationAttributes.getString("module");
if (StringUtils.hasText(moduleConfigBeanName)) {
addPropertyReference(builder, "module", moduleConfigBeanName);
}
// 获取注解上配置的注册中心的beanName
String[] registryConfigBeanNames = serviceAnnotationAttributes.getStringArray("registry");
List<RuntimeBeanReference> registryRuntimeBeanReferences = toRuntimeBeanReferences(registryConfigBeanNames);
if (!registryRuntimeBeanReferences.isEmpty()) {
builder.addPropertyValue("registries", registryRuntimeBeanReferences);
}
String[] protocolConfigBeanNames = serviceAnnotationAttributes.getStringArray("protocol");
List<RuntimeBeanReference> protocolRuntimeBeanReferences = toRuntimeBeanReferences(protocolConfigBeanNames);
if (!protocolRuntimeBeanReferences.isEmpty()) {
builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
}
return builder.getBeanDefinition();
}
private ManagedList<RuntimeBeanReference> toRuntimeBeanReferences(String... beanNames) {
ManagedList<RuntimeBeanReference> runtimeBeanReferences = new ManagedList<>();
if (!ObjectUtils.isEmpty(beanNames)) {
for (String beanName : beanNames) {
String resolvedBeanName = environment.resolvePlaceholders(beanName);
runtimeBeanReferences.add(new RuntimeBeanReference(resolvedBeanName));
}
}
return runtimeBeanReferences;
}
private String generateServiceBeanName(AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass) {
ServiceBeanNameBuilder builder = create(interfaceClass, environment)
.group(serviceAnnotationAttributes.getString("group"))
.version(serviceAnnotationAttributes.getString("version"));
return builder.build();
}
private Annotation findServiceAnnotation(Class<?> beanClass) {
Annotation service = findMergedAnnotation(beanClass, Service.class);
if (service == null) {
service = findMergedAnnotation(beanClass, com.alibaba.dubbo.config.annotation.Service.class);
}
return service;
}
}

通过ReferenceAnnotationBeanPostProcessor后置处理器处理@Reference注解,在该后置处理器的构造方法中调用了超类AnnotationInjectedBeanPostProcessor的构造方法传入了需要处理的注解类型。而AnnotationInjectedBeanPostProcessor又是InstantiationAwareBeanPostProcessorAdapter的子类,在属性赋值阶段会调用其postProcessPropertyValues方法,在该方法中通过调用findInjectionMetadata先从缓存中获取,获取不到再通过buildAnnotatedMetadata方法中调用findFieldAnnotationMetadatafindAnnotatedMethodMetadata方法遍历筛选出该BeanClass中的所有被@Reference注解标注的属性和方法,将其分别封装到AnnotatedFieldElementAnnotatedMethodElement中。

再将所有的信息封装到InjectionMetadata的子类AnnotatedInjectionMetadata中,然后调用InjectionMetadatainject方法完成属性的注入,该方法中会遍历调用AnnotatedFieldElementAnnotatedMethodElement中的inject方法,然后调用getInjectedObject方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor implements ApplicationContextAware, ApplicationListener {
public ReferenceAnnotationBeanPostProcessor() {
super(Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
}
}
public abstract class AnnotationInjectedBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, BeanClassLoaderAware, EnvironmentAware, DisposableBean {
public AnnotationInjectedBeanPostProcessor(Class<? extends Annotation>... annotationTypes) {
this.annotationTypes = annotationTypes;
}
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs); // 寻找需要注入的属性即被@Reference标注的Field
try {
metadata.inject(bean, beanName, pvs);
} catch (BeanCreationException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getSimpleName() + " dependencies is failed", ex);
}
return pvs;
}
private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
try {
metadata = buildAnnotatedMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
} catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() + "] for annotation metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}
private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
// 获取beanClass中Filed上有@Reference注解Field列表
Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
// 获取beanClass中方法上有@Reference注解方法列表
Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
// 返回的是Dubbo定义的AnnotatedInjectionMetadata,接下来就会使用这个类去进行属性注入
return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
}
private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {
final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>();
ReflectionUtils.doWithFields(beanClass, field -> { // 遍历beanClass的所有属性
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) { // 遍历注解列表:Reference.class, com.alibaba.dubbo.config.annotation.Reference.class
AnnotationAttributes attributes = getMergedAttributes(field, annotationType, getEnvironment(), true);
if (attributes != null) { // 若该属性上目标注解属性存在
if (Modifier.isStatic(field.getModifiers())) {
return; // 若为static方法直接跳过
}
elements.add(new AnnotatedFieldElement(field, attributes));
}
}
});
return elements;
}
private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {
final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>();
ReflectionUtils.doWithMethods(beanClass, method -> {
Method bridgedMethod = findBridgedMethod(method);
if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
AnnotationAttributes attributes = getMergedAttributes(bridgedMethod, annotationType, getEnvironment(), true);
if (attributes != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
if (Modifier.isStatic(method.getModifiers())) {
return;
}
// 找到set方法所对应的属性
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
elements.add(new AnnotatedMethodElement(method, pd, attributes));
}
}
});
return elements;
}
protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception {
// 哪个Service应用了哪个类型的服务,通过什么方式引入的
String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement);
// cacheKey很鸡肋,属性名不一样的时候,cacheKey不一样,导致不能缓存, 在一个Service中@Reference两次同一个服务缓存不到
Object injectedObject = injectedObjectsCache.get(cacheKey);
if (injectedObject == null) {
injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement); // 生成Bean
injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
}
return injectedObject;
}
}
private class AnnotatedMethodElement extends InjectionMetadata.InjectedElement {
private final Method method;
private final AnnotationAttributes attributes;
private volatile Object object;
protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, AnnotationAttributes attributes) {
super(method, pd);
this.method = method;
this.attributes = attributes;
}
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { // set方法对应的属性的类型
Class<?> injectedType = pd.getPropertyType();
// 从Spring容器中获取一个Bean(注意,这个方法内部会生成Bean而且会缓存,就像Spring中的getBean一样)
Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
ReflectionUtils.makeAccessible(method);
method.invoke(bean, injectedObject); // 调用set方法
}
}
public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement {
private final Field field;
private final AnnotationAttributes attributes;
private volatile Object bean;
protected AnnotatedFieldElement(Field field, AnnotationAttributes attributes) {
super(field, null);
this.field = field;
this.attributes = attributes;
}
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {// 给bean对象进行属性赋值
Class<?> injectedType = field.getType();
Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this); // 获取对象,然后进行注入
ReflectionUtils.makeAccessible(field);
field.set(bean, injectedObject); // 字段赋值,injectedObject就是值
}
}

最终调用ReferenceAnnotationBeanPostProcessordoGetInjectedBean方法,首先构建一个ReferenceBean对象并对其属性赋值等操作,然后将其注册到Spring容器中,若容器中已存在则注册一个别名,最后通过getOrCreateProxy方法判断当前调用的Dubbo服务是本地服务还是远程服务,若是本地服务则通过newProxyInstance创建代理对象,若是远程服务则调用ReferenceBeanget方法创建代理对象。

ReferenceBean对象的构建及其属性赋值是通过AnnotatedInterfaceConfigBeanBuilderbuild方法来完成的,将各种配置项包括@Reference注解中的配置项赋值给ReferenceBean对应属性,然后调用ReferenceBeanafterPropertiesSet方法完成属性进一步赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor implements ApplicationContextAware, ApplicationListener {
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
return buildReferencedBeanName(attributes, injectedType) + "#source=" + (injectedElement.getMember()) + "#attributes=" + AnnotationUtils.resolvePlaceholders(attributes, getEnvironment());
}
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) throws Exception {
// 按ServiceBean的beanName生成规则来生成referencedBeanName,规则为ServiceBean:interfaceClassName:version:group
String referencedBeanName = buildReferencedBeanName(attributes, injectedType);
// @Reference(methods=[Lorg.apache.dubbo.config.annotation.Method;@39b43d60) org.apache.dubbo.demo.DemoService
String referenceBeanName = getReferenceBeanName(attributes, injectedType); // 根据@Reference注解的信息生成referenceBeanName
ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referenceBeanName, attributes, injectedType); // 生成一个ReferenceBean对象
registerReferenceBean(referencedBeanName, referenceBean, attributes, injectedType); // 把referenceBean添加到Spring容器中去
cacheInjectedReferenceBean(referenceBean, injectedElement);
// 创建一个代理对象,Service中的属性被注入的就是这个代理对象,内部会调用referenceBean.get();
return getOrCreateProxy(referencedBeanName, referenceBeanName, referenceBean, injectedType);
}
private ReferenceBean buildReferenceBeanIfAbsent(String referenceBeanName, AnnotationAttributes attributes, Class<?> referencedType) throws Exception {
ReferenceBean<?> referenceBean = referenceBeanCache.get(referenceBeanName);
if (referenceBean == null) {// 生成了一个ReferenceBean对象,attributes是@Reference注解的参数值
ReferenceBeanBuilder beanBuilder = ReferenceBeanBuilder.create(attributes, applicationContext).interfaceClass(referencedType);
referenceBean = beanBuilder.build(); // 构建ReferenceBean对象并对属性赋值
referenceBeanCache.put(referenceBeanName, referenceBean);
} else if (!referencedType.isAssignableFrom(referenceBean.getInterfaceClass())) {
throw new IllegalArgumentException("reference bean name " + referenceBeanName + " has been duplicated, but interfaceClass " + referenceBean.getInterfaceClass().getName() + " cannot be assigned to " + referencedType.getName());
}
return referenceBean;
}
private void registerReferenceBean(String referencedBeanName, ReferenceBean referenceBean, AnnotationAttributes attributes, Class<?> interfaceClass) {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
String beanName = getReferenceBeanName(attributes, interfaceClass); // 就是referenceBeanName
// 当前Spring容器中是否存在referencedBeanName
if (existsServiceBean(referencedBeanName)) { // If @Service bean is local one
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition(referencedBeanName);
RuntimeBeanReference runtimeBeanReference = (RuntimeBeanReference) beanDefinition.getPropertyValues().get("ref"); // ServiceBean --- ref
String serviceBeanName = runtimeBeanReference.getBeanName(); // DemoServiceImpl对应的beanName
beanFactory.registerAlias(serviceBeanName, beanName); // DemoServiceImpl多了一个别名,比如 demoServiceImpl和
} else { // Remote @Service Bean
if (!beanFactory.containsBean(beanName)) {
beanFactory.registerSingleton(beanName, referenceBean);
}
}
}
private Object getOrCreateProxy(String referencedBeanName, String referenceBeanName, ReferenceBean referenceBean, Class<?> serviceInterfaceType) {
if (existsServiceBean(referencedBeanName)) { // If the local @Service Bean exists, build a proxy of ReferenceBean
return newProxyInstance(getClassLoader(), new Class[]{serviceInterfaceType}, wrapInvocationHandler(referenceBeanName, referenceBean));
} else { // ReferenceBean should be initialized and get immediately
return referenceBean.get(); // 重点
}
}
}
public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInterfaceConfig> {
public final C build() throws Exception {
checkDependencies();
C configBean = doBuild(); // 创建一个ReferenceBean对象
configureBean(configBean); // 给ReferenceBean对象的属性赋值
return configBean;
}
protected void configureBean(C configBean) throws Exception {
preConfigureBean(attributes, configBean); // 把@Reference注解中的配置项赋值给configBean
configureRegistryConfigs(configBean); // 把注册中心配置项赋值给configBean
configureMonitorConfig(configBean);// 把监控中心配置项赋值给configBean
configureApplicationConfig(configBean);// 把应用配置项赋值给configBean
configureModuleConfig(configBean);
// 设置applicationContext、interfaceName、consumer、methods属性,并调用ReferenceBean对象的afterPropertiesSet方法
postConfigureBean(attributes, configBean);
}
private void configureRegistryConfigs(C configBean) {
String[] registryConfigBeanIds = resolveRegistryConfigBeanNames(attributes); // 解析@Refrence注解中配置的registry属性
// 获得注册中心对应的RegistryConfig对象
List<RegistryConfig> registryConfigs = getBeans(applicationContext, registryConfigBeanIds, RegistryConfig.class);
configBean.setRegistries(registryConfigs); // 设置registryConfigs属性值
}
private void configureMonitorConfig(C configBean) {
String monitorBeanName = resolveMonitorConfigBeanName(attributes);
// 从Spring容器获取MonitorConfig的bean对象
MonitorConfig monitorConfig = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
configBean.setMonitor(monitorConfig);
}
private void configureApplicationConfig(C configBean) {
String applicationConfigBeanName = resolveApplicationConfigBeanName(attributes);
ApplicationConfig applicationConfig = getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
configBean.setApplication(applicationConfig);
}
private void configureModuleConfig(C configBean) {
String moduleConfigBeanName = resolveModuleConfigBeanName(attributes);
ModuleConfig moduleConfig = getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
configBean.setModule(moduleConfig);
}
}
class ReferenceBeanBuilder extends AnnotatedInterfaceConfigBeanBuilder<ReferenceBean> {
protected ReferenceBean doBuild() {
return new ReferenceBean<Object>();
}
protected void preConfigureBean(AnnotationAttributes attributes, ReferenceBean referenceBean) {
Assert.notNull(interfaceClass, "The interface class must set first!");
DataBinder dataBinder = new DataBinder(referenceBean);
dataBinder.registerCustomEditor(String.class, "filter", new StringTrimmerEditor(true));
dataBinder.registerCustomEditor(String.class, "listener", new StringTrimmerEditor(true));
// 最终都会转变为Map设置到referenceBean中的parameters,@Reference(parameters = {"text=123"})或@Reference(parameters = {"text:123"})两种配置方式
dataBinder.registerCustomEditor(Map.class, "parameters", new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws java.lang.IllegalArgumentException {
String content = StringUtils.trimAllWhitespace(text); // Trim all whitespace
if (!StringUtils.hasText(content)) { // No content , ignore directly
return;
}
content = StringUtils.replace(content, "=", ",");// replace "=" to ","
content = StringUtils.replace(content, ":", ","); // replace ":" to ","
Map<String, String> parameters = CollectionUtils.toStringMap(commaDelimitedListToStringArray(content));
setValue(parameters);
}
});
dataBinder.bind(new AnnotationPropertyValuesAdapter(attributes, applicationContext.getEnvironment(), IGNORE_FIELD_NAMES));
}
protected void postConfigureBean(AnnotationAttributes attributes, ReferenceBean bean) throws Exception {
bean.setApplicationContext(applicationContext);
configureInterface(attributes, bean);
configureConsumerConfig(attributes, bean);
configureMethodConfig(attributes, bean);
bean.afterPropertiesSet();
}
private void configureInterface(AnnotationAttributes attributes, ReferenceBean referenceBean) {
Boolean generic = getAttribute(attributes, "generic");
if (generic != null && generic) { // 泛化接口处理
String interfaceClassName = getAttribute(attributes, "interfaceName");
referenceBean.setInterface(interfaceClassName);
return;
}
Class<?> serviceInterfaceClass = resolveServiceInterfaceClass(attributes, interfaceClass);
referenceBean.setInterface(serviceInterfaceClass);
}
private void configureConsumerConfig(AnnotationAttributes attributes, ReferenceBean<?> referenceBean) {
String consumerBeanName = getAttribute(attributes, "consumer");
ConsumerConfig consumerConfig = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
referenceBean.setConsumer(consumerConfig);
}
void configureMethodConfig(AnnotationAttributes attributes, ReferenceBean<?> referenceBean) {
Method[] methods = (Method[]) attributes.get("methods");
List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(methods);
if (!methodConfigs.isEmpty()) {
referenceBean.setMethods(methodConfigs);
}
}
}

ReferenceBeanReferenceConfig的子类,首先通过checkAndUpdateSubConfigs检查和更新配置,首先通过completeCompoundConfigs方法拿consumermoduleapplication中配置的属性去填充ReferenceConfig相同属性,然后通过startConfigCenter方法若配置了配置中心则开启配置中心,然后从配置中心获取配置数据刷新所有除开ServiceConfigXxConfig中的属性

配置填充补全后在get方法中若refnull,则调用init初始化方法,首先将所有参数解析到Map,根据Map中的参数通过Protocol创建具体的Invoker对象,然后通过ProxyFactorygetProxy方法给Invoker创建代理对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
public class ReferenceConfig<T> extends AbstractReferenceConfig {
public synchronized T get() {
checkAndUpdateSubConfigs();
if (destroyed) {
throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!");
}
if (ref == null) {// 入口
init();
}
return ref; // Invoke代理
}
public void checkAndUpdateSubConfigs() {
if (StringUtils.isEmpty(interfaceName)) {
throw new IllegalStateException("<dubbo:reference interface=\"\" /> interface not allow null!");
}
completeCompoundConfigs(); // 填充ReferenceConfig对象中的属性
startConfigCenter(); // 开启配置中心,
checkDefault(); // get consumer's global configuration
this.refresh(); // 刷新ReferenceConfig对象的属性值
if (getGeneric() == null && getConsumer() != null) { // 设置泛化
setGeneric(getConsumer().getGeneric());
}
if (ProtocolUtils.isGeneric(getGeneric())) {
interfaceClass = GenericService.class;
} else {
try {
interfaceClass = Class.forName(interfaceName, true, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
checkInterfaceAndMethods(interfaceClass, methods);
}
resolveFile();
checkApplication();
checkMetadataReport();
}
private void init() {
if (initialized) {
return;
}
checkStubAndLocal(interfaceClass);
checkMock(interfaceClass);
Map<String, String> map = new HashMap<String, String>();
map.put(SIDE_KEY, CONSUMER_SIDE);
appendRuntimeParameters(map);
if (!ProtocolUtils.isGeneric(getGeneric())) {
String revision = Version.getVersion(interfaceClass, version);
if (revision != null && revision.length() > 0) {
map.put(REVISION_KEY, revision);
}
String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
if (methods.length == 0) {
map.put(METHODS_KEY, ANY_VALUE);
} else {
map.put(METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), COMMA_SEPARATOR));
}
}
map.put(INTERFACE_KEY, interfaceName);
appendParameters(map, metrics);
appendParameters(map, application);
appendParameters(map, module);
appendParameters(map, consumer);
appendParameters(map, this);
Map<String, Object> attributes = null;
if (CollectionUtils.isNotEmpty(methods)) {
attributes = new HashMap<String, Object>();
for (MethodConfig methodConfig : methods) {
appendParameters(map, methodConfig, methodConfig.getName());
String retryKey = methodConfig.getName() + ".retry";
if (map.containsKey(retryKey)) {
String retryValue = map.remove(retryKey);
if ("false".equals(retryValue)) {
map.put(methodConfig.getName() + ".retries", "0");
}
}
attributes.put(methodConfig.getName(), convertMethodConfig2AsyncInfo(methodConfig));
}
}
String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
if (StringUtils.isEmpty(hostToRegistry)) {
hostToRegistry = NetUtils.getLocalHost();
} else if (isInvalidLocalHost(hostToRegistry)) {
throw new IllegalArgumentException("Specified invalid registry ip from property:" + DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
}
map.put(REGISTER_IP_KEY, hostToRegistry);
ref = createProxy(map); // 根据
String serviceKey = URL.buildKey(interfaceName, group, version);
ApplicationModel.initConsumerModel(serviceKey, buildConsumerModel(serviceKey, attributes));
initialized = true;
}
private T createProxy(Map<String, String> map) {
if (shouldJvmRefer(map)) { // 若是本地调用
// injvm://
URL url = new URL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, interfaceClass.getName()).addParameters(map);
invoker = REF_PROTOCOL.refer(interfaceClass, url);
if (logger.isInfoEnabled()) {
logger.info("Using injvm service " + interfaceClass.getName());
}
} else {// 为什么会有urls,因为可以在@Reference的url属性中配置多个url,可以是点对点的服务地址,也可以是注册中心的地址
urls.clear(); // reference retry init will add url to urls, lead to OOM
if (url != null && url.length() > 0) { // @Reference中指定了url属性
String[] us = SEMICOLON_SPLIT_PATTERN.split(url); // 用;号切分
if (us != null && us.length > 0) {
for (String u : us) {
URL url = URL.valueOf(u);
if (StringUtils.isEmpty(url.getPath())) {
url = url.setPath(interfaceName);
}
if (REGISTRY_PROTOCOL.equals(url.getProtocol())) { // 如果是注册中心地址,则在url中添加一个refer参数
urls.add(url.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map))); // map表示消费者端配置的参数
} else {// 如果是服务地址,有可能url中配置了参数,map中表示的服务消费者消费服务时的参数,所以需要合并
urls.add(ClusterUtils.mergeUrl(url, map));
}
}
}
} else { // @Reference中的protocol属性表示使用哪个协议调用服务,如果不是本地调用协议injvm://,则把注册中心地址找出来,对于injvm://协议已经在之前的逻辑中就已经生成invoke了
if (!LOCAL_PROTOCOL.equalsIgnoreCase(getProtocol())) {
checkRegistry();
List<URL> us = loadRegistries(false); // 加载注册中心地址
if (CollectionUtils.isNotEmpty(us)) {
for (URL u : us) {
URL monitorUrl = loadMonitor(u);
if (monitorUrl != null) {
map.put(MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
}
urls.add(u.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map))); // 对于注册中心地址都添加REFER_KEY
}
}
if (urls.isEmpty()) {
throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
}
}
}
if (urls.size() == 1) { // 如果只有一个url则直接refer得到一个invoker
// RegistryProtocol.refer() 或者 DubboProtocol.refer()
invoker = REF_PROTOCOL.refer(interfaceClass, urls.get(0));
// MockClusterInvoker-->FailoverClusterInvoker-->RegistryDirectory
// --->RegistryDirectory$InvokerDelegate-->ListenerInvokerWrapper-->ProtocolFilterWrapper$CallbackRegistrationInvoker-->ConsumerContextFilter-->FutureFilter-->MonitorFilter-->AsyncToSyncInvoker-->DubboInvoker
// --->RegistryDirectory$InvokerDelegate-->ListenerInvokerWrapper-->ProtocolFilterWrapper$CallbackRegistrationInvoker-->ConsumerContextFilter-->FutureFilter-->MonitorFilter-->AsyncToSyncInvoker-->DubboInvoker
} else {
// 如果有多个url根据每个url,refer得到对应的invoker
// 若这多个urls中存在注册中心url,则把所有invoker整合为RegistryAwareClusterInvoker,该Invoker在调用时,会查看所有Invoker中是否有默认的,如果有则使用默认的Invoker,如果没有,则使用第一个Invoker
// 若这多个urls中不存在注册中心url,则把所有invoker整合为FailoverCluster
List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
URL registryURL = null; // 用来记录urls中最后一个注册中心url
for (URL url : urls) {
invokers.add(REF_PROTOCOL.refer(interfaceClass, url));
if (REGISTRY_PROTOCOL.equals(url.getProtocol())) {
registryURL = url; // use last registry url
}
}
if (registryURL != null) { // registry url is available 如果存在注册中心地址
// use RegistryAwareCluster only when register's CLUSTER is available
URL u = registryURL.addParameter(CLUSTER_KEY, RegistryAwareCluster.NAME);
// StaticDirectory表示静态服务目录,里面的invokers是不会变的, 生成一个RegistryAwareCluster
// The invoker wrap relation would be: RegistryAwareClusterInvoker(StaticDirectory) -> FailoverClusterInvoker(RegistryDirectory, will execute route) -> Invoker
invoker = CLUSTER.join(new StaticDirectory(u, invokers));
} else { // not a registry url, must be direct invoke.
// 如果不存在注册中心地址, 生成一个FailoverClusterInvoker
invoker = CLUSTER.join(new StaticDirectory(invokers));
}
}
}
if (shouldCheck() && !invoker.isAvailable()) {
throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
}
MetadataReportService metadataReportService = null;
if ((metadataReportService = getMetadataReportService()) != null) {
URL consumerURL = new URL(CONSUMER_PROTOCOL, map.remove(REGISTER_IP_KEY), 0, map.get(INTERFACE_KEY), map);
metadataReportService.publishConsumer(consumerURL);
}
return (T) PROXY_FACTORY.getProxy(invoker); // create service proxy
}
}
public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
protected List<URL> loadRegistries(boolean provider) {// check && override if necessary
List<URL> registryList = new ArrayList<URL>();
if (CollectionUtils.isNotEmpty(registries)) {
for (RegistryConfig config : registries) {
String address = config.getAddress();
if (StringUtils.isEmpty(address)) { // 如果注册中心没有配地址,则地址为0.0.0.0
address = ANYHOST_VALUE;
}
if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) { // 如果注册中心的地址不是"N/A"
Map<String, String> map = new HashMap<String, String>();
appendParameters(map, application); // 把application中的参数放入map中,注意,map中的key是没有prefix的
appendParameters(map, config); // 把config中的参数放入map中,注意,map中的key是没有prefix的config是RegistryConfig,表示注册中心
map.put(PATH_KEY, RegistryService.class.getName());// 此处path值固定为RegistryService.class.getName(),因为现在是在加载注册中心
appendRuntimeParameters(map); // 把dubbo的版本信息和pid放入map中
if (!map.containsKey(PROTOCOL_KEY)) { // 如果map中如果没有protocol,那么默认为dubbo
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
}
List<URL> urls = UrlUtils.parseURLs(address, map); // 构造注册中心url,地址+参数
for (URL url : urls) {
url = URLBuilder.from(url).addParameter(REGISTRY_KEY, url.getProtocol()).setProtocol(REGISTRY_PROTOCOL).build();
// 到此为止,url的内容大概为:registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=dubbo-demo-annotation-provider&dubbo=2.0.2&pid=269936&registry=zookeeper&timestamp=1584886077813
// 该url表示:使用registry协议调用org.apache.dubbo.registry.RegistryService服务,参数为application=dubbo-demo-annotation-provider&dubbo=2.0.2&pid=269936&registry=zookeeper&timestamp=1584886077813
// 若是服务提供者,获取register的值,如果为false,表示该服务不注册到注册中心,若是服务消费者,获取subscribe的值,如果为false,表示该引入的服务不订阅注册中心中的数据
if ((provider && url.getParameter(REGISTER_KEY, true)) || (!provider && url.getParameter(SUBSCRIBE_KEY, true))) {
registryList.add(url);
}
}
}
}
}
return registryList;
}
}