一、示例
1.dubbo-common
<groupId>org.example</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0.0</version>
public interface Server1 {
String method1();
String method2();
}
2.spring-boot-dubbo-provider1
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>org.example</groupId>
<artifactId>spring-boot-dubbo-provider1</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
application.yml
# 服务端口
server:
port: 18001
# dubbo 配置
dubbo:
# 应用
application:
name: provider1
qos-enable: false
# register-mode: all # 接口级+应用级均注册,接口级注册与应用级注册并存(/dubbo && /service),应用升级到 dubbo 3.0 后,服务端自动开启接口级 + 应用级双注册功能,默认无需开发者修改任何配置
register-mode: interface # 只接口级注册(/dubbo)
# register-mode: instance # 只应用级注册(/service)
# 注册中心地址
registry:
address: zookeeper://127.0.0.1:12181
# group: group_1
timeout: 300000 # 连接超时时间,默认 30s
session: 600000 # 会话超时时间,默认 60s
provider:
timeout: 300000
# 协议
protocol:
name: dubbo
port: 21881 # 默认 20880
@DubboService(version = "1.0", group = "dev_group")
public class Server1Impl implements Server1 {
@Override
public String method1() {
return "this is provider1 Service1#method1()";
}
@Override
public String method2() {
return "this is provider1 Service1#method2()";
}
}
@RestController
public class IndexController {
@DubboReference(version = "1.0", group = "dev_group")
private Server1 server1;
@RequestMapping("/")
public String index(){
String result = server1.method1();
return result;
}
}
@SpringBootApplication
@EnableDubbo
public class Provider1Boot {
/*
@DubboService 会生成两个 Bean
1)
beanName: server1Impl
bean: Server1Impl
beanFactory.getBean("server1Impl") 和 beanFactory.getBean(Server1.class) 可找到此 Bean
2)
ServiceBean:com.example.common.server.Server1:1.0:dev_group
bean: ServiceBean
beanFactory.getBean("com.example.common.server.Server1:1.0:dev_group") 和
*/
public static void main(String[] args) {
SpringApplication.run(Provider1Boot.class, args);
}
}
3.spring-boot-dubbo-consumer1
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/>
</parent>
<groupId>org.example</groupId>
<artifactId>spring-boot-dubbo-consumer1</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>dubbo-common</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
application.yml
# 服务端口
server:
port: 19001
# dubbo 配置
dubbo:
# 应用
application:
name: consumer1
qos-enable: false
# register-mode: all # 接口级+应用级均注册,接口级注册与应用级注册并存(/dubbo && /service),应用升级到 dubbo 3.0 后,服务端自动开启接口级 + 应用级双注册功能,默认无需开发者修改任何配置
register-mode: interface # 只接口级注册(/dubbo)
# register-mode: instance # 只应用级注册(/service)
# 注册中心地址
registry:
address: zookeeper://127.0.0.1:12181
# group: group_1
timeout: 300000 # 连接超时时间,默认 30s
session: 600000 # 会话超时时间,默认 60s
consumer:
timeout: 300000
retries: 0
# 协议
protocol:
name: dubbo
port: 21883
@RestController
public class IndexController {
@DubboReference(version = "1.0", group = "dev_group")
private Server1 server1;
@RequestMapping("/")
public String index(){
String result = server1.method1();
return result;
}
}
@SpringBootApplication
public class Consumer1Boot {
/*
@DubboReference 会生成一个 Bean
1. 扫描到 @DubboReference
beanName: server1
bean: $Proxy62
beanFactory.getBean("server1") 和 beanFactory.getBean(Server1.class) 可找到此 Bean
*/
public static void main(String[] args) {
SpringApplication.run(Consumer1Boot.class, args);
}
}
二、原理
1.注册 DubboConfigConfigurationRegistrar 和 DubboComponentScanRegistrar
@EnableDubbo
// EnableDubbo.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@EnableDubboConfig
@DubboComponentScan
public @interface EnableDubbo
// EnableDubboConfig.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Import(DubboConfigConfigurationRegistrar.class)
public @interface EnableDubboConfig
// DubboComponentScan.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboComponentScanRegistrar.class)
public @interface DubboComponentScan
2.DubboConfigConfigurationRegistrar
registerContextBeans() 方法,注册 bean:
1.beanName: org.apache.dubbo.config.spring.context.DubboSpringInitContext
bean: DubboSpringInitContext
2.beanName: org.apache.dubbo.rpc.model.ApplicationModel
bean: ApplicationModel
3.beanName: org.apache.dubbo.rpc.model.ModuleModel
bean: ModuleModel
4.beanName: dubboServicePackagesHolder
bean: ServicePackagesHolder
5.beanName: dubboReferenceBeanManager
bean: ReferenceBeanManager
6.beanName: referenceAnnotationBeanPostProcessor
bean: ReferenceAnnotationBeanPostProcessor
有 postProcessBeanFactory() 方法
7.beanName: dubboConfigAliasPostProcessor
bean: DubboConfigAliasPostProcessor
8.beanName: org.apache.dubbo.config.spring.context.DubboDeployApplicationListener
bean: DubboDeployApplicationListener
有 setApplicationContext() 方法
9.beanName: org.apache.dubbo.config.spring.context.DubboConfigApplicationListener
bean: DubboConfigApplicationListener
有 onApplicationEvent() 方法
10.beabName: dubboConfigDefaultPropertyValueBeanPostProcessor
bean: DubboConfigDefaultPropertyValueBeanPostProcessor
有 processBeforeInitialization() 方法
11.beanName: dubboConfigBeanInitializer
bean: DubboConfigBeanInitializer
有 afterPropertiesSet() 方法
12.beanName: dubboInfraBeanRegisterPostProcessor
bean: DubboInfraBeanRegisterPostProcessor
有 postProcessBeanFactory() 方法
// DubboConfigConfigurationRegistrar.java
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
DubboSpringInitializer.initialize(registry);
}
// DubboSpringInitializer.java
public static void initialize(BeanDefinitionRegistry registry) {
if (contextMap.putIfAbsent(registry, new DubboSpringInitContext()) != null) {
return;
}
DubboSpringInitContext context = contextMap.get(registry);
// find beanFactory
ConfigurableListableBeanFactory beanFactory = findBeanFactory(registry);
// init dubbo context
initContext(context, registry, beanFactory);
}
private static void initContext(DubboSpringInitContext context, BeanDefinitionRegistry registry,
ConfigurableListableBeanFactory beanFactory) {
context.setRegistry(registry);
context.setBeanFactory(beanFactory);
customize(context);
ModuleModel moduleModel = context.getModuleModel();
if (moduleModel == null) {
ApplicationModel applicationModel;
if (findContextForApplication(ApplicationModel.defaultModel()) == null) {
applicationModel = ApplicationModel.defaultModel();
} else {
applicationModel = FrameworkModel.defaultModel().newApplication();
}
moduleModel = applicationModel.getDefaultModule();
context.setModuleModel(moduleModel);
}
registerContextBeans(beanFactory, context);
context.markAsBound();
moduleModel.setLifeCycleManagedExternally(true);
DubboBeanUtils.registerCommonBeans(registry);
}
private static void registerContextBeans(ConfigurableListableBeanFactory beanFactory, DubboSpringInitContext context) {
registerSingleton(beanFactory, context);
registerSingleton(beanFactory, context.getApplicationModel());
registerSingleton(beanFactory, context.getModuleModel());
}
private static void registerSingleton(ConfigurableListableBeanFactory beanFactory, Object bean) {
beanFactory.registerSingleton(bean.getClass().getName(), bean);
}
// DubboBeanUtils.java
static void registerCommonBeans(BeanDefinitionRegistry registry) {
registerInfrastructureBean(registry, ServicePackagesHolder.BEAN_NAME, ServicePackagesHolder.class);
registerInfrastructureBean(registry, ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class);
// Since 2.5.7 Register @Reference Annotation Bean Processor as an infrastructure Bean
registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME,
ReferenceAnnotationBeanPostProcessor.class);
// TODO Whether DubboConfigAliasPostProcessor can be removed ?
// Since 2.7.4 [Feature] https://github.com/apache/dubbo/issues/5093
registerInfrastructureBean(registry, DubboConfigAliasPostProcessor.BEAN_NAME,
DubboConfigAliasPostProcessor.class);
// register ApplicationListeners
registerInfrastructureBean(registry, DubboDeployApplicationListener.class.getName(), DubboDeployApplicationListener.class);
registerInfrastructureBean(registry, DubboConfigApplicationListener.class.getName(), DubboConfigApplicationListener.class);
// Since 2.7.6 Register DubboConfigDefaultPropertyValueBeanPostProcessor as an infrastructure Bean
registerInfrastructureBean(registry, DubboConfigDefaultPropertyValueBeanPostProcessor.BEAN_NAME,
DubboConfigDefaultPropertyValueBeanPostProcessor.class);
// Dubbo config initializer
registerInfrastructureBean(registry, DubboConfigBeanInitializer.BEAN_NAME, DubboConfigBeanInitializer.class);
// register infra bean if not exists later
registerInfrastructureBean(registry, DubboInfraBeanRegisterPostProcessor.BEAN_NAME, DubboInfraBeanRegisterPostProcessor.class);
}
2.DubboComponentScanRegistrar
registerServiceAnnotationPostProcessor() 方法,依次从 @DubboComponentScan、@EnableDubbo、启动类,获得扫描的包路径
注册 bean:
1.beanName: org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationPostProcessor#0
bean: ServiceAnnotationPostProcessor
// DubboComponentScanRegistrar.java
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// initialize dubbo beans
DubboSpringInitializer.initialize(registry);
Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);
registerServiceAnnotationPostProcessor(packagesToScan, registry);
}
private Set<String> getPackagesToScan(AnnotationMetadata metadata) {
// get from @DubboComponentScan
Set<String> packagesToScan = getPackagesToScan0(metadata, DubboComponentScan.class, "basePackages", "basePackageClasses");
// get from @EnableDubbo, compatible with spring 3.x
if (packagesToScan.isEmpty()) {
packagesToScan = getPackagesToScan0(metadata, EnableDubbo.class, "scanBasePackages", "scanBasePackageClasses");
}
if (packagesToScan.isEmpty()) {
return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName()));
}
return packagesToScan;
}
private void registerServiceAnnotationPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationPostProcessor.class);
builder.addConstructorArgValue(packagesToScan);
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
}
3.ServiceAnnotationPostProcessor
扫描注解
1.@org.apache.dubbo.config.annotation.DubboService
2.@org.apache.dubbo.config.annotation.Service
3.@com.alibaba.dubbo.config.annotation.Service.class
doScan(basePackages) 方法,会扫描注解 @org.apache.dubbo.config.annotation.DubboService、@org.apache.dubbo.config.annotation.Service、@com.alibaba.dubbo.config.annotation.Service
把符合的 bean,注册 BeanDefinition 到 spring 容器
beanName: server1Impl
beanDefinition: ScannedGenericBeanDefinition,其中 beanClass 是 com.example.provider.server.Server1Impl
processScannedBeanDefinition(beanDefinitionHolder) 方法,注册 BeanDefinition 到 spring 容器
beaName: ServiceBean:com.example.common.server.Server1:1.0:dev_group
beanDefinition: RootBeanDefinition,其中 beanClass 是 ServiceBean
// ServiceAnnotationPostProcessor.java
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
this.registry = registry;
scanServiceBeans(resolvedPackagesToScan, registry);
}
private void scanServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {
scanned = true;
...
DubboClassPathBeanDefinitionScanner scanner =
new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
scanner.setBeanNameGenerator(beanNameGenerator);
for (Class<? extends Annotation> annotationType : serviceAnnotationTypes) {
scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
}
ScanExcludeFilter scanExcludeFilter = new ScanExcludeFilter();
scanner.addExcludeFilter(scanExcludeFilter);
for (String packageToScan : packagesToScan) {
...
scanner.scan(packageToScan);
Set<BeanDefinitionHolder> beanDefinitionHolders =
findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
...
for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
processScannedBeanDefinition(beanDefinitionHolder);
servicePackagesHolder.addScannedClass(beanDefinitionHolder.getBeanDefinition().getBeanClassName());
}
} else {
...
}
servicePackagesHolder.addScannedPackage(packageToScan);
}
}
private void processScannedBeanDefinition(BeanDefinitionHolder beanDefinitionHolder) {
Class<?> beanClass = resolveClass(beanDefinitionHolder);
Annotation service = findServiceAnnotation(beanClass);
// The attributes of @Service annotation
Map<String, Object> serviceAnnotationAttributes = AnnotationUtils.getAttributes(service, true);
String serviceInterface = resolveInterfaceName(serviceAnnotationAttributes, beanClass);
String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
// ServiceBean Bean name
String beanName = generateServiceBeanName(serviceAnnotationAttributes, serviceInterface);
AbstractBeanDefinition serviceBeanDefinition =
buildServiceBeanDefinition(serviceAnnotationAttributes, serviceInterface, annotatedServiceBeanName);
registerServiceBeanDefinition(beanName, serviceBeanDefinition, serviceInterface);
}
private AbstractBeanDefinition buildServiceBeanDefinition(Map<String, Object> serviceAnnotationAttributes,
String serviceInterface,
String refServiceBeanName) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ServiceBean.class);
...
return builder.getBeanDefinition();
}
// ClassPathBeanDefinitionScanner.java
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
doScan(basePackages);
...
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
...
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
...
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
4.ReferenceAnnotationBeanPostProcessor 注册 bean
扫描注解
@org.apache.dubbo.config.annotation.DubboReference
@org.apache.dubbo.config.annotation.Reference
@com.alibaba.dubbo.config.annotation.Reference
循环 beanDefinitionNames,找到成员变量和方法,标注 @org.apache.dubbo.config.annotation.DubboReference、@org.apache.dubbo.config.annotation.Reference、@com.alibaba.dubbo.config.annotation.Reference 的成员变量和方法,把扫描到的成员变量和方法,注册到 spring,并注册到 referenceBeanManager
beanName: server1
beanDefinition: RootBeanDefinition,其中 beanClass 是 org.apache.dubbo.config.spring.ReferenceBean
referenceKey: ReferenceBean:dev_group/com.example.common.server.Server1:1.0()
referenceBeanName: server1
// ReferenceAnnotationBeanPostProcessor.java
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
Class<?> beanType;
if (beanFactory.isFactoryBean(beanName)) {
...
} else {
beanType = beanFactory.getType(beanName);
}
if (beanType != null) {
AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
try {
prepareInjection(metadata);
} catch (BeansException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Prepare dubbo reference injection element failed", e);
}
}
}
...
try {
applicationContext.publishEvent(new DubboConfigInitEvent(applicationContext));
} catch (Exception e) {
...
}
}
protected AnnotatedInjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (needsRefreshInjectionMetadata(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (needsRefreshInjectionMetadata(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
try {
metadata = buildAnnotatedMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
} catch (NoClassDefFoundError err) {
...
}
}
}
}
return metadata;
}
private AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
Collection<AbstractAnnotationBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
Collection<AbstractAnnotationBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
return new AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
}
protected void prepareInjection(AnnotatedInjectionMetadata metadata) throws BeansException {
try {
for (AnnotatedFieldElement fieldElement : metadata.getFieldElements()) {
if (fieldElement.injectedObject != null) {
continue;
}
Class<?> injectedType = fieldElement.field.getType();
AnnotationAttributes attributes = fieldElement.attributes;
String referenceBeanName = registerReferenceBean(fieldElement.getPropertyName(), injectedType, attributes, fieldElement.field);
//associate fieldElement and reference bean
fieldElement.injectedObject = referenceBeanName;
injectedFieldReferenceBeanCache.put(fieldElement, referenceBeanName);
}
for (AnnotatedMethodElement methodElement : metadata.getMethodElements()) {
if (methodElement.injectedObject != null) {
continue;
}
Class<?> injectedType = methodElement.getInjectedType();
AnnotationAttributes attributes = methodElement.attributes;
String referenceBeanName = registerReferenceBean(methodElement.getPropertyName(), injectedType, attributes, methodElement.method);
//associate methodElement and reference bean
methodElement.injectedObject = referenceBeanName;
injectedMethodReferenceBeanCache.put(methodElement, referenceBeanName);
}
} catch (ClassNotFoundException e) {
...
}
}
public String registerReferenceBean(String propertyName, Class<?> injectedType, Map<String, Object> attributes, Member member) throws BeansException {
...
// check reference key
String referenceKey = ReferenceBeanSupport.generateReferenceKey(attributes, applicationContext);
// find reference bean name by reference key
List<String> registeredReferenceBeanNames = referenceBeanManager.getBeanNamesByKey(referenceKey);
if (registeredReferenceBeanNames.size() > 0) {
// found same name and reference key
if (registeredReferenceBeanNames.contains(referenceBeanName)) {
return referenceBeanName;
}
}
...
Class interfaceClass = injectedType;
// Register the reference bean definition to the beanFactory
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClassName(ReferenceBean.class.getName());
beanDefinition.getPropertyValues().add(ReferenceAttributes.ID, referenceBeanName);
// set attribute instead of property values
beanDefinition.setAttribute(Constants.REFERENCE_PROPS, attributes);
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
// create decorated definition for reference bean, Avoid being instantiated when getting the beanType of ReferenceBean
// see org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean()
GenericBeanDefinition targetDefinition = new GenericBeanDefinition();
targetDefinition.setBeanClass(interfaceClass);
beanDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, referenceBeanName + "_decorated"));
// signal object type since Spring 5.2
beanDefinition.setAttribute(Constants.OBJECT_TYPE_ATTRIBUTE, interfaceClass);
beanDefinitionRegistry.registerBeanDefinition(referenceBeanName, beanDefinition);
referenceBeanManager.registerReferenceKeyAndBeanName(referenceKey, referenceBeanName);
logger.info("Register dubbo reference bean: " + referenceBeanName + " = " + referenceKey + " at " + member);
return referenceBeanName;
}
5.ReferenceAnnotationBeanPostProcessor 注入属性
1.执行 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName) 方法,调用 ReferenceAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition(mbd, beanType, beanName) 方法,扫描@org.apache.dubbo.config.annotation.DubboReference、@org.apache.dubbo.config.annotation.Reference、@com.alibaba.dubbo.config.annotation.Reference 注解,把符合的成员变量绑定的 BeanDefinition,
并从 spring 容器中,获得对应的 bean (若没有注册,则会注册到 spring 容器) 的 beanName,绑定到 BeanDefinition
2.执行 populateBean(beanName, mbd, bw) 方法,调用 ReferenceAnnotationBeanPostProcessor 的 postProcessProperties(pvs, bean, beanName) 方法,进行把值赋值给成员变量
// DefaultListableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
...
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
...
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
...
mbd.postProcessed = true;
}
}
...
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
...
}
...
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
...
}
...
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
...
}
// ReferenceAnnotationBeanPostProcessor.java
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
if (isReferenceBean(beanDefinition)) {
...
} else if (isAnnotatedReferenceBean(beanDefinition)) {
...
} else {
AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
try {
prepareInjection(metadata);
} catch (Exception e) {
...
}
}
}
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
try {
AnnotatedInjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
prepareInjection(metadata);
metadata.inject(bean, beanName, pvs);
}
...
return pvs;
}
protected void prepareInjection(AnnotatedInjectionMetadata metadata) throws BeansException {
try {
//find and register bean definition for @DubboReference/@Reference
for (AnnotatedFieldElement fieldElement : metadata.getFieldElements()) {
if (fieldElement.injectedObject != null) {
continue;
}
Class<?> injectedType = fieldElement.field.getType();
AnnotationAttributes attributes = fieldElement.attributes;
String referenceBeanName = registerReferenceBean(fieldElement.getPropertyName(), injectedType, attributes, fieldElement.field);
//associate fieldElement and reference bean
fieldElement.injectedObject = referenceBeanName;
injectedFieldReferenceBeanCache.put(fieldElement, referenceBeanName);
}
for (AnnotatedMethodElement methodElement : metadata.getMethodElements()) {
if (methodElement.injectedObject != null) {
continue;
}
Class<?> injectedType = methodElement.getInjectedType();
AnnotationAttributes attributes = methodElement.attributes;
String referenceBeanName = registerReferenceBean(methodElement.getPropertyName(), injectedType, attributes, methodElement.method);
//associate methodElement and reference bean
methodElement.injectedObject = referenceBeanName;
injectedMethodReferenceBeanCache.put(methodElement, referenceBeanName);
}
} catch (ClassNotFoundException e) {
throw new BeanCreationException("prepare reference annotation failed", e);
}
}
protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
AnnotatedInjectElement injectedElement) throws Exception {
return doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
}
@Override
protected Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
AnnotatedInjectElement injectedElement) throws Exception {
if (injectedElement.injectedObject == null) {
throw new IllegalStateException("The AnnotatedInjectElement of @DubboReference should be inited before injection");
}
return getBeanFactory().getBean((String) injectedElement.injectedObject);
}
// AbstractAnnotationBeanPostProcessor$AnnotatedInjectionMetadata
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
}
}
this.checkedElements = checkedElements;
}
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
// AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement.java
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Object injectedObject = getInjectedObject(attributes, bean, beanName, getInjectedType(), this);
if (member instanceof Field) {
Field field = (Field) member;
ReflectionUtils.makeAccessible(field);
field.set(bean, injectedObject);
} else if (member instanceof Method) {
Method method = (Method) member;
ReflectionUtils.makeAccessible(method);
method.invoke(bean, injectedObject);
}
}