五Dubbo服务引用源码分析--1消费端启动
五Dubbo服务引用源码分析--1消费端启动
在消费端consumer引用服务进行分析时,首先看Dubbo的开发者手册,把握分析的切入点,并全局把握大致的流程。
1 服务消费的过程中,首先是引用配置的初始化--即ReferenceConfig初始化,需要加载consumer.xml配置信息,将referenceBean的beandefinition加载入spring的IOC容器的beanDefinitionMap中;
2 然后,完成实例化并初始化referenceBean的过程中,执行referenceConfig.init()方法,调用protocol.refer方法生成Invoker实例(此处是consumer端的关键);
3 随后把invoker转换为客户端需要的接口;
4 服务调用的过程中,调用referenceBean.getObject获取代理对象,然后执行服务的引用操作。
服务引用部分,仍旧以DubboDemo为例,进行源码追踪与分析。

consumer端启动代码如下:

5.0 消费端启动(初始化)
对于ReferenceBean,其继承结构如下
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
public Object getObject() throws Exception {
return get();
}
/**referenceConfig方法
public synchronized T get() {
if (destroyed) {
throw new IllegalStateException("Already destroyed!");
}
if (ref == null) {
init();
}
return ref; ref是referenceBean所代理的目标类,所创建的代理类对象
}*/
//初始化方法
public void afterPropertiesSet() throws Exception {
1 可知其实现了bean的周期方法的接口,在初始化时调用;
2 此外,实现FactoryBean,getBean获取对象时,通过getObject获取真正的bean;
3 然后继承ReferenceConfig,实现了dubbo的消费端信息的配置。
5.0.1 解析referenceBean的xml
在启动consumer端后,解析consumer.xml中配置的dubbo:reference的配置信息
解析后,在spring的IOC容器中的beanDefinitionMap中加入如下的beandefinition定义:


将ReferenceBean以permissionService的id存入IOC容器的map中。
5.0.2 初始化referenceBean
在初始化bean时,会根据自定义的Initmethod方法,完成对ReferenceBean的初始化工作。
TAG1 referenceBean自定义初始化
referenceBean
@SuppressWarnings({ "unchecked"})
public void afterPropertiesSet() throws Exception {
//初始化过程中,此处为null
if (getConsumer() == null) {
Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false);
if (consumerConfigMap != null && consumerConfigMap.size() > 0) {
ConsumerConfig consumerConfig = null;
for (ConsumerConfig config : consumerConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (consumerConfig != null) {
throw new IllegalStateException("Duplicate consumer configs: " + consumerConfig + " and " + config);
}
consumerConfig = config;
}
}
if (consumerConfig != null) {
setConsumer(consumerConfig);
}
}
}
if (getApplication() == null
&& (getConsumer() == null || getConsumer().getApplication() == null)) {
//referenceBean实现applicationContextAware,会自动注入,此处applicationContext不为null
//然后这里从spring的applicationContext种获取在xml内配置的dubbo的ApplicationConfig
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
ApplicationConfig applicationConfig = null;
for (ApplicationConfig config : applicationConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (applicationConfig != null) {
throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
}
applicationConfig = config;
}
}
if (applicationConfig != null) {
//设置referenceBean的dubbo-applicationConfig
setApplication(applicationConfig);
}
}
}
if (getModule() == null
&& (getConsumer() == null || getConsumer().getModule() == null)) {
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
ModuleConfig moduleConfig = null;
for (ModuleConfig config : moduleConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (moduleConfig != null) {
throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
}
moduleConfig = config;
}
}
if (moduleConfig != null) {
setModule(moduleConfig);
}
}
}
if ((getRegistries() == null || getRegistries().size() == 0)
&& (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().size() == 0)
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
//然后这里从spring的applicationContext种获取在xml内配置的dubbo的RegistryConfig
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
registryConfigs.add(config);
}
}
if (registryConfigs != null && registryConfigs.size() > 0) {
//设置referenceBean的注册中心配置
super.setRegistries(registryConfigs);
}
}
}
if (getMonitor() == null
&& (getConsumer() == null || getConsumer().getMonitor() == null)
&& (getApplication() == null || getApplication().getMonitor() == null)) {
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
MonitorConfig monitorConfig = null;
for (MonitorConfig config : monitorConfigMap.values()) {
if (config.isDefault() == null || config.isDefault().booleanValue()) {
if (monitorConfig != null) {
throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
}
monitorConfig = config;
}
}
if (monitorConfig != null) {
setMonitor(monitorConfig);
}
}
}
//是否在加载时,立刻getObject()初始化ReferenceBean---默认懒加载
Boolean b = isInit();
if (b == null && getConsumer() != null) {
b = getConsumer().isInit();
}
if (b != null && b.booleanValue()) {
getObject();
}
}
在ReferenceBean的afterPropertiesSet方法中,初始化referenceConfig的applicationConfig、registryConfig等属性。

ReferenceBean的过程,总结如下:

其中,interfaceClass属性,用来匹配IOC容器内factoryBean.getObject()所代理创建的对象的类型。用来在applicationContext.getBean(DemoService.class)匹配IOC中的beanname。
TAG2 ReferenceBean.getBean(DemoService.class)执行时机
TAG2.0 Dubbo2.6.4及以下版本问题(2.6.9)
在spring容器实例化(不是初始化过程)时,总是发现ReferenceBean在存入spring一级缓存后,它的ref(就是DemoService服务类的动态代理类被默认初始化创建了,但是没有执行ReferenceBean.getObject()初始化ref这一步。

个人调试源码过程中,使用的Dubbo2.5.3,发现在跟踪源码调试ReferenceBean,了解ref的代理创建过程时候,总是遇到这个问题,也调试和纠结了许久,后来发现是2.6.4及以下版本的问题,并且在pull request #2754 中已经修复该问题,并在Dubbo2.6.5版本中修改。如果使用低版本dubbo,可以按如下修改IDEA默认的配置:

这里,是在debug模式下,取消"toString"的override。因为,在debug模式下,IDEA会通过toString()方法,获取对象对应的信息。而在ReferenceBean执行过程中,显示信息执行的toString(),调用的是父类AbstractConfig.toString()方法:
public String toString() {
try {
StringBuilder buf = new StringBuilder();
buf.append("<dubbo:");
buf.append(getTagName(getClass()));
//获取当前config类内方法对象
Method[] methods = getClass().getMethods();
for (Method method : methods) {
try {
String name = method.getName();
//这里没有过滤掉getObject()方法
if ((name.startsWith("get") || name.startsWith("is"))
&& !"getClass".equals(name) && !"get".equals(name) && !"is".equals(name)
&& Modifier.isPublic(method.getModifiers())
&& method.getParameterTypes().length == 0
&& isPrimitive(method.getReturnType())) {
int i = name.startsWith("get") ? 3 : 2;
String key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
//getObject方法被反射调用,从而实现referenceBean中ref的初始化操作
Object value = method.invoke(this);
if (value != null) {
buf.append(" ");
buf.append(key);
buf.append("=\"");
buf.append(value);
buf.append("\"");
}
}
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
buf.append(" />");
return buf.toString();
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
return super.toString();
}
}
从上述的过程知道出问题以及在debug模式下修改的原因。
TAG2.1 ReferenceBean初始化
referenceBean作为FactoryBean类,其在执行实例化、初始化后,会最终向一级缓存中添加如下的k:v对:
key(permissionService):value(ReferenceBean)。此时,已经执行完TAG1的自定义初始化过程。

此时,一级缓存中存储name为"permissionService"、具体实例为ReferenceBean。此时,referenceBean内代理对象ref,尚未经过getObject()进行创建代理对象。
TAG2.2 context.getObject调用时机(spring相关内容)
对于服务引用获取的DemoService,不是要referenceBean实例,而是获取远程调用的代理对象,并通过该proxy对象调用远程dubbo服务。

在5.0中,向IOC容器的beandefinitionMap中传入permissionService=beanDefinition(referencenBean),然后跟入context.getBean(DemoService.class)
AbstractApplicationContext
//根据DemoService.class类型,获取bean
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
DefaultListableBeanFactory
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
DefaultListableBeanFactory
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
//获取type类型在spring的IOC容器中的对象
Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
if (resolved == null) {
throw new NoSuchBeanDefinitionException(requiredType);
}
return (T) resolved;
}
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
//TAG0 resolveNamedBean 根据类型type,获取springIOC中的bean
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent instanceof DefaultListableBeanFactory) {
return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
}
else if (parent != null) {
ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
if (args != null) {
return parentProvider.getObject(args);
}
else {
return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
}
}
return null;
}
//TAG0 resolveNamedBean
private <T> NamedBeanHolder<T> resolveNamedBean(
ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
//TAG1 getBeanNamesForType
//对于getBean(type),对于参数type类型,获取IOC容器中对应的beanName
//逻辑:从beanFactory的beannames中遍历,并获取beandefinition,如果当前bean是factoryBean,获取其参数interfaceClass,表示当前factoryBean的getBean获取的具体对象类型
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
for (String beanName : candidateNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (!autowireCandidates.isEmpty()) {
candidateNames = StringUtils.toStringArray(autowireCandidates);
}
}
//根据type只匹配到一个候选者时
if (candidateNames.length == 1) {
//TAG2 resolveNamedBean
//"permissionService",DemoService---获取对应的bean
return resolveNamedBean(candidateNames[0], requiredType, args);
}
else if (candidateNames.length > 1) {
Map<String, Object> candidates = CollectionUtils.newLinkedHashMap(candidateNames.length);
for (String beanName : candidateNames) {
if (containsSingleton(beanName) && args == null) {
Object beanInstance = getBean(beanName);
candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
}
else {
candidates.put(beanName, getType(beanName));
}
}
String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
if (candidateName == null) {
candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance == null) {
return null;
}
if (beanInstance instanceof Class) {
return resolveNamedBean(candidateName, requiredType, args);
}
return new NamedBeanHolder<>(candidateName, (T) beanInstance);
}
if (!nonUniqueAsNull) {
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
}
}
return null;
}
//TAG2 resolveNamedBean
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
String beanName, ResolvableType requiredType, @Nullable Object[] args) throws BeansException {
//然后根据匹配到的beanname,获取bean对象
Object bean = getBean(beanName, null, args);
if (bean instanceof NullBean) {
return null;
}
return new NamedBeanHolder<T>(beanName, adaptBeanInstance(beanName, bean, requiredType.toClass()));
}
getBeanNamesForType方法中,根据getBean(type)传入的类型,从springIOC注册的beandefinitionNames中遍历,并获取beandefinition,如果当前bean是factoryBean,获取其参数interfaceClass,表示当前factoryBean的getBean获取的具体对象类型。其匹配逻辑如下:


AbstractBeanFactory
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name);
Object beanInstance;
//从缓存中获取
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//TAG1
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else{……………………略}
AbstractBeanFactory
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
/** ………………………………………………略*/
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//this.factoryBeanObjectCache中获取(尚未缓存)
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从factoryBean的getObject获取对象
//TAG1
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
FactoryBeanRegistrySupport
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//从factoryBean中getObject对象,缓存
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//TAG2
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//存入缓存
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//这里从ReferenceBean.getObject()获取demoService对象
object = factory.getObject();
}
}
从factoryBean.getObject()获取对象后,会以demoservice:proxy$0为k:v键值对,存入spring的FactoryBeanObjectCache缓存中。


浙公网安备 33010602011771号