Demo
SpringBoot整合Dubbo只需加个依赖,服务提供者加注解@Service (dubbo的不是spring的,后改为@DubboService),服务消费者加注解@Reference注解
加依赖
<!-- Dubbo集成进SpringBoot -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
<!-- zookeeper所需依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.8</version>
<type>pom</type>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
服务提供者
@Service(group = "default", version = "1.0")
@Slf4j
public class DemoServiceImpl implements DemoService {
@Override
public String called(String name) {
URL url = RpcContext.getContext().getUrl();
String msg = url.getProtocol() + ":" + url.getPort() + ",Hello," + name;
log.info(msg);
return msg;
}
}
服务消费者
@RestController
@Slf4j
public class DemoServiceController {
@Reference(group = "default", version = "1.0", cache = "lru")
private DemoService demoService;
@RequestMapping("/default")
public String test() {
return demoService.called("默认服务");
}
}
入口
任何框架与SpringBoot集成都是通过starter包和autoconfigure进行集成,我们首先看到jar包依赖这边我们依赖了dubbo-spring-boot-starter。

我们看到这2个autoconfigure下的spring.factories


这里我们重点关注DubboAutoConfiguration这个类
DubboAutoConfiguration
这个类的重点是@EnableDubboConfig和ServiceClassPostProcessor
功能:
@EnableDubboConfig去解析配置类- 把
ServiceClassPostProcessor后置处理器通过springboot自动装配注入到spring中
这里我们一步一步的来看
@EnableDubboConfig
打开这个类我们发现@Import(DubboConfigConfigurationRegistrar.class),DubboConfigConfigurationRegistrar这个类重写了ImportBeanDefinitionRegistrar(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)方法,这个方法包含参数BeanDefinitionRegistry,Dubbo可以通过BeanDefinitionRegistry注册BeanDefinition。(Spring Import相关知识)
DubboConfigConfigurationRegistrar
public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 获取EnableDubboConfig上面的信息,这里主要获取的是multiple的值默认为true
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableDubboConfig.class.getName()));
// 获取EnableDubboConfig标签中的multiple属性默认为true
boolean multiple = attributes.getBoolean("multiple");
// 注册bean定义 ===== 重点 ===========
registerBeans(registry, DubboConfigConfiguration.Single.class);
if (multiple) { // Since 2.6.6 https://github.com/apache/dubbo/issues/3193
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
}
// Since 2.7.6
// 注册公共的bean,5个
// ReferenceAnnotationBeanPostProcessor,DubboConfigAliasPostProcessor,
// DubboLifecycleComponentApplicationListener,DubboBootstrapApplicationListener,
// DubboConfigDefaultPropertyValueBeanPostProcessor
registerCommonBeans(registry);
}
}
需要注意的是这里注册了ReferenceAnnotationBeanPostProcessor,这个Bean后置处理器和解析@Reference相关
public static void registerBeans(BeanDefinitionRegistry registry, Class<?>... annotatedClasses) {
Set<Class<?>> classesToRegister = new LinkedHashSet<Class<?>>(asList(annotatedClasses));
Iterator<Class<?>> iterator = classesToRegister.iterator();
// 已经被注册过得Bean不在重新注册,移除classesToRegister中已注册过的bean
while (iterator.hasNext()) {
Class<?> annotatedClass = iterator.next();
if (isPresentBean(registry, annotatedClass)) {
iterator.remove();
}
}
// 通过AnnotatedBeanDefinitionReader批量注册classesToRegister
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
reader.register(classesToRegister.toArray(EMPTY_CLASS_ARRAY));
}
DubboConfigConfiguration
public class DubboConfigConfiguration {
// 通过前缀(prefix)去spring的environment中匹配,并通过后置处理器将值绑定到类(type)中,生成beanDefinition
@EnableConfigurationBeanBindings({
@EnableConfigurationBeanBinding(prefix = "dubbo.application", type = ApplicationConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.module", type = ModuleConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.registry", type = RegistryConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.monitor", type = MonitorConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.provider", type = ProviderConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metrics", type = MetricsConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.ssl", type = SslConfig.class)
})
public static class Single {
}
@EnableConfigurationBeanBindings({
@EnableConfigurationBeanBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.config-centers", type = ConfigCenterBean.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.metadata-reports", type = MetadataReportConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true)
})
public static class Multiple {
}
}
观察这个类中包含了Multiple和Single2个子类,而这2个子类上都有@EnableConfigurationBeanBindings注解。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ConfigurationBeanBindingsRegister.class)
public @interface EnableConfigurationBeanBindings {
EnableConfigurationBeanBinding[] value();
}
注解上同样import了一个类ConfigurationBeanBindingsRegister,发现这个类实现了ImportBeanDefinitionRegistrar, EnvironmentAware2个类,知道spring的都知道ImportBeanDefinitionRegistrar表明了可以注册beanDefinition,EnvironmentAware表明可以设置环境。
public class ConfigurationBeanBindingsRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private ConfigurableEnvironment environment;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 获取@EnableConfigurationBeanBindings注解上的所有属性值
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableConfigurationBeanBindings.class.getName()));
// 拿到多个@EnableDubboConfigBinding注解
AnnotationAttributes[] annotationAttributes = attributes.getAnnotationArray("value");
ConfigurationBeanBindingRegistrar registrar = new ConfigurationBeanBindingRegistrar();
registrar.setEnvironment(environment);
for (AnnotationAttributes element : annotationAttributes) {
// 逐个解析@EnableDubboConfigBinding注解 ======这个方法可以看下============
registrar.registerConfigurationBeanDefinitions(element, registry);
}
}
@Override
public void setEnvironment(Environment environment) {
Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
this.environment = (ConfigurableEnvironment) environment;
}
}
ConfigurationBeanBindingRegistrar#registerConfigurationBeanDefinitions
- DubboConfigConfiguration下的@EnableDubboConfigBinding注解
- 通过@EnableDubboConfigBinding注解中的前缀匹配到配置文件中的配置项
- 通过@EnableDubboConfigBinding中class和配置项生成bean定义
- 注册bean定义
// @EnableDubboConfigBinding注解上的所有值
public void registerConfigurationBeanDefinitions(Map<String, Object> attributes, BeanDefinitionRegistry registry) {
String prefix = getRequiredAttribute(attributes, "prefix");
prefix = environment.resolvePlaceholders(prefix);
Class<?> configClass = getRequiredAttribute(attributes, "type");
boolean multiple = getAttribute(attributes, "multiple", valueOf(DEFAULT_MULTIPLE));
boolean ignoreUnknownFields = getAttribute(attributes, "ignoreUnknownFields", valueOf(DEFAULT_IGNORE_UNKNOWN_FIELDS));
boolean ignoreInvalidFields = getAttribute(attributes, "ignoreInvalidFields", valueOf(DEFAULT_IGNORE_INVALID_FIELDS));
// ===================重要方法===================
registerConfigurationBeans(prefix, configClass, multiple, ignoreUnknownFields, ignoreInvalidFields, registry);
}
private void registerConfigurationBeans(String prefix, Class<?> configClass, boolean multiple,
boolean ignoreUnknownFields, boolean ignoreInvalidFields,
BeanDefinitionRegistry registry) {
// 从配置文件中根据前缀拿对应的配置项
Map<String, Object> configurationProperties = PropertySourcesUtils.getSubProperties(environment.getPropertySources(), environment, prefix);
// multiple控制是否会存在有多个bean,比如
/*dubbo.protocols.p1.id=dubbo1
dubbo.protocols.p1.name=dubbo
dubbo.protocols.p1.port=20881
dubbo.protocols.p1.host=0.0.0.0
dubbo.protocols.p2.id=dubbo1
dubbo.protocols.p2.name=dubbo
dubbo.protocols.p2.port=20881
dubbo.protocols.p2.host=0.0.0.0*/
// 这种讲道理应该生成多个bean,而且这多个bean直接按protocols后的p1,p2命名
Set<String> beanNames = multiple ? resolveMultipleBeanNames(configurationProperties) :
singleton(resolveSingleBeanName(configurationProperties, configClass, registry));
// 注册上面解析出来的beanName为beanDefinition,,但需要注意的是这里只是beanDeinition,其中的属性值并没有设置,是在bean的后置处理器中处理
// 在注册过程中beanDefinition.setSource(ENABLE_CONFIGURATION_BINDING_CLASS);后面会bean后置处理器会通过它区分bean是否是这里引过去的
for (String beanName : beanNames) {
registerConfigurationBean(beanName, configClass, multiple, ignoreUnknownFields, ignoreInvalidFields,
configurationProperties, registry);
}
// 注册一个ConfigurationBeanBindingPostProcessor的Bean后置处理器
registerConfigurationBindingBeanPostProcessor(registry);
}
ConfigurationBeanBindingPostProcessor
主要解决的是之前只是注册了beanDefinition,属性值并没有设到bean中,我们需要在bean实例化之前进行属性赋值,所以需要在bean的后置处理器中进行处理。
我们发现ConfigurationBeanBindingPostProcessor实现了BeanPostProcessor,并且实现了postProcessBeforeInitialization接口,从这里可以看出实例化之前调用postProcessBeforeInitialization接口进行属性赋值。
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 获取beanDefinition
BeanDefinition beanDefinition = getNullableBeanDefinition(beanName);
// 判断bean是不是@EnableConfigurationBeanBinding注册的bean
if (isConfigurationBean(bean, beanDefinition)) {
// 属性值绑定到bean上
bindConfigurationBean(bean, beanDefinition);
customize(beanName, bean);
}
return bean;
}
ServiceClassPostProcessor
这个类主要干的事就是扫描包,注册beanDefinition,由于它实现了BeanDefinitionRegistryPostProcessor,是一个bean工厂的后置处理器(可以注册bean定义)
有个注意点,Dubbo扫描包注册成的beanDefinition不是一个是2个,一个是Spring的BeanDefinition还有一个是Dubbo的ServiceBean,为什么还需要一个Dubbo的ServiceBean,因为Dubbo如果仅仅只使用Spring的BeanDefinition会缺少很多@Service的注解信息,Dubbo会利用@Service上的信息进行填充产生一个新的bean-ServiceBean。而且用自己的bean可以做很多的处理
所以在扫描到⼀个@Service注解后,其实会得到两个Bean:
- 服务实现类本身Bean对象
- 对应的ServiceBean类型的Bean对象
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// @since 2.7.5
// 注册一个事件监听器,spring事件为ContextRefreshedEvent时,会调用dubboBootstrap.start();
registerInfrastructureBean(registry, DubboBootstrapApplicationListener.BEAN_NAME, DubboBootstrapApplicationListener.class);
// 获取包扫描路径
Set<String> resolvedPackagesToScan = resolvePackagesToScan(packagesToScan);
if (!CollectionUtils.isEmpty(resolvedPackagesToScan)) {
// 扫描包,注册ServiceBean ========重点===========
registerServiceBeans(resolvedPackagesToScan, registry);
} else {
if (logger.isWarnEnabled()) {
logger.warn("packagesToScan is empty , ServiceBean registry will be ignored!");
}
}
}
ServiceAnnotationBeanPostProcessor#registerServiceBeans
- 扫描被标注了@DubboService和@Service注解的类
- 注册bean
// ====================去掉了一些不必要的log代码===========
private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
DubboClassPathBeanDefinitionScanner scanner =
new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
scanner.setBeanNameGenerator(beanNameGenerator);
// refactor @since 2.7.7
// 扫描一些有注解的类,这注解主要有3种(不同版本不一样,需注意)
// DubboService.class,(新版本,与Spring区分)
// org.apache.dubbo.config.annotation.Service,(老版本)
// com.alibaba.dubbo.config.annotation.Service.class(兼容)
serviceAnnotationTypes.forEach(annotationType -> {
scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
});
for (String packageToScan : packagesToScan) {
// Registers @Service Bean first
// 调用Spring的scan方法会生成beanDefinition最后生成了bean,这就是服务实现类本身Bean对象
scanner.scan(packageToScan);
// 查找被@Service注解的类的BeanDefinition(无论这个类有没有被@ComponentScan注解标注了)
Set<BeanDefinitionHolder> beanDefinitionHolders =
findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
// 扫描到BeanDefinition开始处理它
for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
// ============================核心方法=====================
registerServiceBean(beanDefinitionHolder, registry, scanner);
}
}
}
}
ServiceAnnotationBeanPostProcessor#registerServiceBean
注册Bean
private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
DubboClassPathBeanDefinitionScanner scanner) {
// 服务实现类
Class<?> beanClass = resolveClass(beanDefinitionHolder);
// 拿到注解,这里拿到的是@Service
Annotation service = findServiceAnnotation(beanClass);
// 获取注解上的属性值(这里也包括了缺省值)
AnnotationAttributes serviceAnnotationAttributes = getAnnotationAttributes(service, false, false);
// 服务实现类的接口类
Class<?> interfaceClass = resolveServiceInterfaceClass(serviceAnnotationAttributes, beanClass);
// 服务实现类对应的bean的名字
String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
// 构建ServiceBeanDefinition 这个过程可以看下==========================稍重点====================
AbstractBeanDefinition serviceBeanDefinition =
buildServiceBeanDefinition(service, serviceAnnotationAttributes, interfaceClass, annotatedServiceBeanName);
// ServiceBean的名字
String beanName = generateServiceBeanName(serviceAnnotationAttributes, interfaceClass);
// 检查重复的候选bean
if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { // check duplicated candidate bean
// ServiceBean注册为beanDefinition
registry.registerBeanDefinition(beanName, serviceBeanDefinition);
}
}
buildServiceBeanDefinition
生成一个ServiceBean对应的BeanDefinition
private AbstractBeanDefinition buildServiceBeanDefinition(Annotation serviceAnnotation,
AnnotationAttributes serviceAnnotationAttributes,
Class<?> interfaceClass,
String annotatedServiceBeanName) {
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceBean.class);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
// 把serviceAnnotation中的参数值赋值给ServiceBean的属性
// 忽略掉一些属性,因为这些属性不能做简单的属性赋值,需要经过一些操作,
// 比如protocol这个是需要引用的是bean,而不是字符串,这里我们就要通过字符串去找到bean赋值
String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol",
"interface", "interfaceName", "parameters");
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")));
// Add methods parameters
List<MethodConfig> methodConfigs = convertMethodConfigs(serviceAnnotationAttributes.get("methods"));
if (!methodConfigs.isEmpty()) {
builder.addPropertyValue("methods", methodConfigs);
}
// 下面也是一些参数的赋值,就删掉了。。。。。。
// beanDefinition返回
return builder.getBeanDefinition();
}
generateServiceBeanName
生成ServiceBean的bean名称
逻辑很简单就是把group,version等拼接
private String generateServiceBeanName(AnnotationAttributes serviceAnnotationAttributes, Class<?> interfaceClass) {
ServiceBeanNameBuilder builder = create(interfaceClass, environment)
.group(serviceAnnotationAttributes.getString("group"))
.version(serviceAnnotationAttributes.getString("version"));
return builder.build();
}

ReferenceAnnotationBeanPostProcessor
这个后置处理器主要是针对于@Reference生成ReferenceBean并进行依赖注入
在@EnableDubboConfig下的DubboConfigConfigurationRegistrar类中registerCommonBeans方法注入了ReferenceAnnotationBeanPostProcessor后置处理器我们发现这个后置处理器实现了InstantiationAwareBeanPostProcessor.postProcessPropertyValues这个方法,而这个方法是在依赖注入的时候调用的。
// 构造方法中传入三个匹配注解,存到annotationTypes,后面匹配的时候会使用存到annotationTypes
public ReferenceAnnotationBeanPostProcessor() {
super(DubboReference.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
}
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 寻找需要注入的属性被@Reference注解
// 这里通过构造方法配置的DubboReference.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class中找到注解的方法或字段
// AnnotatedFieldElement AnnotatedMethodElement
InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
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;
}
buildAnnotatedMetadata
private AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
Collection<AbstractAnnotationBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
Collection<AbstractAnnotationBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
return new AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
}
doGetInjectedBean
注入调用栈
metadata.inject->element.inject->AnnotatedFieldElement#inject->getInjectedObject->doGetInjectedBean
@Override
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
InjectionMetadata.InjectedElement injectedElement) throws Exception {
/**
* The name of bean that annotated Dubbo's {@link Service @Service} in local Spring {@link ApplicationContext}
*/
// 生成referencedBeanName, 规则ServiceBean:interfaceClassName:version:group
// 是本地的ServiceBean(当前应用自己提供的ServiceBean)
// 例: ServiceBean:com.dm.DemoService:1.0:default
String referencedBeanName = buildReferencedBeanName(attributes, injectedType);
/**
* The name of bean that is declared by {@link Reference @Reference} annotation injection
*/
// 根据@Reference注解的信息生成referenceBeanName
// 这里是把它作为key值,为了区分相同注入相同实现类却不是相同属性的类比如
/*
@Reference(group=default)
private DemoService demoService1;
@Reference(group=hhh)
private DemoService demoService2;
*/
// 例:@Reference(group=default,cache=lru,version=1.0) com.dm.DemoService
String referenceBeanName = getReferenceBeanName(attributes, injectedType);
// 生成一个ReferenceBean对象(这里是会判断缓存中是不是有,有就会使用之前的类)
ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referenceBeanName, attributes, injectedType);
// 判断spring容器中是否有这个serviceBean
boolean localServiceBean = isLocalServiceBean(referencedBeanName, referenceBean, attributes);
prepareReferenceBean(referencedBeanName, referenceBean, localServiceBean);
// 注册referenceBean到Spring容器
// 这里面会首先判断spring是不是有这个ServiceBean,有的话直接注册一个referencedBeanName的别名,没有的话就以referencedBeanName为beanName注册一个beanDefinition
registerReferenceBean(referencedBeanName, referenceBean, attributes, localServiceBean, injectedType);
cacheInjectedReferenceBean(referenceBean, injectedElement);
// 获取一个代理对象
return referenceBean.get();
}
总结
这里的总结分为三部分
配置文件的解析与生成多个配置bean(ApplicationConfig, ModuleConfig,RegistryConfig.class,ProtocolConfig)
- 通过DubboConfigConfiguration#Single或Multiple配置的前缀和配置类
- 通过前缀和配置类去spring的environment进行匹配,然后将匹配获取的值存入配置类的BeanDefinition中
- 通过bean后置处理器在Bean实例化之前进行属性绑定
- 完整bean生成
扫描@Service并生成ServiceBean
- 通过bean工厂的后置处理器扫描有@Service,@DubboService标注的类
- 扫描后会生成一个当前实现类的beanDefinition(spring生成的)
- 然后生成一个Dubbo的beanDefinition实现ServiceBean,目的为了可以处理跟多Dubbo逻辑,还有存储@Service注解上的属性值
注入属性@Reference
- 在Bean的后置处理器中调用postProcessPropertyValues方法处理
- 首先扫描注入点也就是被@Reference,@DubboReference注解的方法和类
- 根据@Reference中的注解信息(group,version)生成一个新的baneName为referencedBeanName,
- 根据@Reference中的注解信息(group,version)生成一个新的baneName为缓存key值为referenceBeanName,
- 判断容器中是不是有referencedBeanName(有,是因为当前注入的类是本项目@DubboService标注的类);有注册一个referencedBeanName的别名,没有的话就以referencedBeanName为beanName注册一个beanDefinition
- 然后创建一个代理对象进行依赖注入(这里为什么要创建代理对象呢?直接使用beanDefinition生成bean不行吗?简单来说就是和ServiceBean创建代理对象一个道理,它会有一些Dubbo逻辑处理在其中,还会依赖存储一些属性值)