dubbo 加载Bean和远程调用分析(1)

这里只讲解dubbo注册的bean

1. dubbo consumer 加载bean  

dubbo-2.5.3.jar!/spring.handlers

  1. http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler  
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

DubboNamespaceHandler 是dubbo命名空间自定义配置文件的解析处理器

  1. public class DubboNamespaceHandler extends NamespaceHandlerSupport {  
  2.   
  3.     static {  
  4.         Version.checkDuplicate(DubboNamespaceHandler.class);  
  5.     }  
  6.   
  7.     public void init() {  
  8.         registerBeanDefinitionParser("application"new DubboBeanDefinitionParser(ApplicationConfig.classtrue));  
  9.         registerBeanDefinitionParser("module"new DubboBeanDefinitionParser(ModuleConfig.classtrue));  
  10.         registerBeanDefinitionParser("registry"new DubboBeanDefinitionParser(RegistryConfig.classtrue));  
  11.         registerBeanDefinitionParser("monitor"new DubboBeanDefinitionParser(MonitorConfig.classtrue));  
  12.         registerBeanDefinitionParser("provider"new DubboBeanDefinitionParser(ProviderConfig.classtrue));  
  13.         registerBeanDefinitionParser("consumer"new DubboBeanDefinitionParser(ConsumerConfig.classtrue));  
  14.         registerBeanDefinitionParser("protocol"new DubboBeanDefinitionParser(ProtocolConfig.classtrue));  
  15.         registerBeanDefinitionParser("service"new DubboBeanDefinitionParser(ServiceBean.classtrue));  
  16.         registerBeanDefinitionParser("reference"new DubboBeanDefinitionParser(ReferenceBean.classfalse));  
  17.         registerBeanDefinitionParser("annotation"new DubboBeanDefinitionParser(AnnotationBean.classtrue));  
  18.     }  
  19.   
  20. }  
public class DubboNamespaceHandler extends NamespaceHandlerSupport {

	static {
		Version.checkDuplicate(DubboNamespaceHandler.class);
	}

	public void init() {
	    registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
    }

}


spring会根据xml的命名空间调用响应的Parser进行处理,进入 DubboBeanDefinitionParser的解析parse

  1. private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {  
  2.         RootBeanDefinition beanDefinition = new RootBeanDefinition();  
  3.         beanDefinition.setBeanClass(beanClass);  
  4.         beanDefinition.setLazyInit(false);  
  5.         String id = element.getAttribute("id");  
  6.         省略....   
  7.         if (id != null && id.length() > 0) {  
  8.             if (parserContext.getRegistry().containsBeanDefinition(id))  {  
  9.                 throw new IllegalStateException("Duplicate spring bean id " + id);  
  10.             }  
  11.             parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);//这里调用了bean的注册  
  12.             beanDefinition.getPropertyValues().addPropertyValue("id", id);  
  13.         }  
  14.         省略....   
  15. }  
private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);
        String id = element.getAttribute("id");
        省略.... 
        if (id != null && id.length() > 0) {
            if (parserContext.getRegistry().containsBeanDefinition(id))  {
        		throw new IllegalStateException("Duplicate spring bean id " + id);
        	}
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);//这里调用了bean的注册
            beanDefinition.getPropertyValues().addPropertyValue("id", id);
        }
        省略.... 
}

这一步注意,虽然注册的bean id(如 demoService) 是与privider端的service的id相同的,但是这里beanDefinition的beanClass却不是自己定义的某个接口了。

在spring解析配置beans时先生成bean的定义,然后getBean时,是通过className获取Class,然后设置bd.setBeanClass(class)

org.springframework.beans.factory.support.AbstractBeanFactory

  1. private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {  
  2.     if (!ObjectUtils.isEmpty(typesToMatch)) {  
  3.         ClassLoader tempClassLoader = getTempClassLoader();  
  4.         if (tempClassLoader != null) {  
  5.             if (tempClassLoader instanceof DecoratingClassLoader) {  
  6.                 DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;  
  7.                 for (Class<?> typeToMatch : typesToMatch) {  
  8.                     dcl.excludeClass(typeToMatch.getName());  
  9.                 }  
  10.             }  
  11.             String className = mbd.getBeanClassName();  
  12.             return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);  
  13.         }  
  14.     }  
  15.     return mbd.resolveBeanClass(getBeanClassLoader());  
  16. }  
	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
		if (!ObjectUtils.isEmpty(typesToMatch)) {
			ClassLoader tempClassLoader = getTempClassLoader();
			if (tempClassLoader != null) {
				if (tempClassLoader instanceof DecoratingClassLoader) {
					DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
					for (Class<?> typeToMatch : typesToMatch) {
						dcl.excludeClass(typeToMatch.getName());
					}
				}
				String className = mbd.getBeanClassName();
				return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
			}
		}
		return mbd.resolveBeanClass(getBeanClassLoader());
	}

在执行 
  1. registerBeanDefinitionParser("reference"new DubboBeanDefinitionParser(ReferenceBean.classfalse));  
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));

时已经将 DubboBeanDefinitionParser.beanClass  = ReferenceBean.class

故在解析时实际是如下形式

  1. RootBeanDefinition beanDefinition = new RootBeanDefinition();  
  2.         beanDefinition.setBeanClass(beanClass); //ReferenceBean.class  
  3.         beanDefinition.setLazyInit(false);  
RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(beanClass); //ReferenceBean.class
        beanDefinition.setLazyInit(false);

即将id=demoService 与 类 
  1. ReferenceBean  
ReferenceBean

绑定,放入map, 即使用的是FactoryBean来创建bean

当spring使用getBean(‘demoService“) 会调用工厂bean的getObject  :  ReferenceBean.getObject

在看看ReferenceBean.getObject

  1. public Object getObject() throws Exception {  
  2.         return get();  
  3.     }  
public Object getObject() throws Exception {
        return get();
    }
  1. public synchronized T get() {  
  2.        if (destroyed){  
  3.            throw new IllegalStateException("Already destroyed!");  
  4.        }  
  5.     if (ref == null) {  
  6.         init();  
  7.     }  
  8.     return ref;  
  9.    }  
 public synchronized T get() {
        if (destroyed){
            throw new IllegalStateException("Already destroyed!");
        }
    	if (ref == null) {
    		init();
    	}
    	return ref;
    }

  1. private void init() {  
  2.    if (initialized) {  
  3.        return;  
  4.    }  
  5.    initialized = true;  
  6.     省略....  
  7.       ref = createProxy(map);//在这里使用了动态代理生成对象  
  8.   }  
  private void init() {
	    if (initialized) {
	        return;
	    }
	    initialized = true;
    	省略....
        ref = createProxy(map);//在这里使用了动态代理生成对象
    }

ref = createProxy(map);//在这里使用了动态代理生成了代理对象(这里也可以成为远程代理,因为在这个代理中进行了远程调用),ref 即getBean返回的对象,这样在action调用demoService是就会使用代理处理器com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler
  1. public class InvokerInvocationHandler implements InvocationHandler {  
  2.   
  3.     private final Invoker<?> invoker;  
  4.       
  5.     public InvokerInvocationHandler(Invoker<?> handler){  
  6.         this.invoker = handler;  
  7.     }  
  8.   
  9.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  10.         String methodName = method.getName();  
  11.         Class<?>[] parameterTypes = method.getParameterTypes();  
  12.         if (method.getDeclaringClass() == Object.class) {  
  13.             return method.invoke(invoker, args);  
  14.         }  
  15.         if ("toString".equals(methodName) && parameterTypes.length == 0) {  
  16.             return invoker.toString();  
  17.         }  
  18.         if ("hashCode".equals(methodName) && parameterTypes.length == 0) {  
  19.             return invoker.hashCode();  
  20.         }  
  21.         if ("equals".equals(methodName) && parameterTypes.length == 1) {  
  22.             return invoker.equals(args[0]);  
  23.         }  
  24.         return invoker.invoke(new RpcInvocation(method, args)).recreate();  
  25.     }  
  26.   
  27. }  
public class InvokerInvocationHandler implements InvocationHandler {

    private final Invoker<?> invoker;
    
    public InvokerInvocationHandler(Invoker<?> handler){
        this.invoker = handler;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (method.getDeclaringClass() == Object.class) {
            return method.invoke(invoker, args);
        }
        if ("toString".equals(methodName) && parameterTypes.length == 0) {
            return invoker.toString();
        }
        if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
            return invoker.hashCode();
        }
        if ("equals".equals(methodName) && parameterTypes.length == 1) {
            return invoker.equals(args[0]);
        }
        return invoker.invoke(new RpcInvocation(method, args)).recreate();
    }

}

看最后一句  invoker.invoke(new RpcInvocation(method, args)).recreate(); 这里就开始进入调用远程的服务 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值