dubbo的consumer只须要在配置文件中配置一个接口的地址,并不须要这个接口有具体的实现类,就能够生成这个接口的代理,经过代理远程调用provider中的方法。html
和JDK还有CGlib不一样,dubbo的consumer生成代理是经过dubbo中的一个com.alibaba.dubbo.common.bytecode.Proxy来生成的,使用了javassist工具来生成代理类的字节码。java
若是在代码中使用spring
Object obj=ApplicationContextUtil.getBean("orderService");
能够发现obj的class并非com.alibaba.dubbo.common.bytecode.Proxy,而是相似com.alibaba.dubbo.common.bytecode.Proxy26这样的(后面的数字不必定是26),这个Proxy26就是最终生成的代理类,他的父类就是Object,可是有对应接口中的方法。app
若是在代码中使用 jvm
Map<String,BeanDefinition> map=ApplicationContextUtil.getBeanDefinitions(); BeanDefinition definition=map.get(service); String className=definition.getBeanClassName();
能够看到className是com.alibaba.dubbo.config.spring.ReferenceBean。ide
dubbo在spring配置文件中的配置能够是这样的:工具
<dubbo:reference id="orderService" interface="test.orderService" protocol="dubbo" check="false"/>
<dubbo >标签是由com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler来解析的。this
DubboNamespaceHandler类是这样的url
packagecom.alibaba.dubbo.config.spring.schema; importcom.alibaba.dubbo.common.Version; importcom.alibaba.dubbo.config.ApplicationConfig; importcom.alibaba.dubbo.config.ConsumerConfig; importcom.alibaba.dubbo.config.ModuleConfig; importcom.alibaba.dubbo.config.MonitorConfig; importcom.alibaba.dubbo.config.ProtocolConfig; importcom.alibaba.dubbo.config.ProviderConfig; importcom.alibaba.dubbo.config.RegistryConfig; importcom.alibaba.dubbo.config.spring.AnnotationBean; importcom.alibaba.dubbo.config.spring.ReferenceBean; importcom.alibaba.dubbo.config.spring.ServiceBean; importorg.springframework.beans.factory.xml.NamespaceHandlerSupport; /** * DubboNamespaceHandler * * @author william.liangf * @export */ public class DubboNamespaceHandler extends NamespaceHandlerSupport { static { Version.checkDuplicate(DubboNamespaceHandler.class); } public void init() { registerBeanDefinitionParser("application", newDubboBeanDefinitionParser(ApplicationConfig.class, true)); registerBeanDefinitionParser("module", newDubboBeanDefinitionParser(ModuleConfig.class, true)); registerBeanDefinitionParser("registry", newDubboBeanDefinitionParser(RegistryConfig.class, true)); registerBeanDefinitionParser("monitor", newDubboBeanDefinitionParser(MonitorConfig.class, true)); registerBeanDefinitionParser("provider",new DubboBeanDefinitionParser(ProviderConfig.class, true)); registerBeanDefinitionParser("consumer", newDubboBeanDefinitionParser(ConsumerConfig.class, true)); registerBeanDefinitionParser("protocol", newDubboBeanDefinitionParser(ProtocolConfig.class, true)); registerBeanDefinitionParser("service", newDubboBeanDefinitionParser(ServiceBean.class, true)); registerBeanDefinitionParser("reference", newDubboBeanDefinitionParser(ReferenceBean.class, false)); registerBeanDefinitionParser("annotation", newDubboBeanDefinitionParser(AnnotationBean.class, true)); } }因此<dubbo:reference>对应的就是com.alibaba.dubbo.config.spring.ReferenceBean
ReferenceBean的定义是这样的:spa
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean,ApplicationContextAware, InitializingBean, DisposableBeanReferenceBean实现了org.springframework.beans.factory.FactoryBean接口,所以ReferenceBean是一个FactoryBean,spring对FactoryBean不会直接构造他的实现类来做为代理类,而是经过FactoryBean的getObject()方法来得到代理类。
ReferenceBean实现了org.springframework.beans.factory.InitializingBean接口,实现了这个接口的类须要实现afterPropertiesSet()方法,而且在初始化结束后调用该方法。dubbo的consumer的代理类也是在这个方法中生成。
ReferenceBean的afterPropertiesSet()方法是这样的:
@SuppressWarnings({"unchecked"}) public void afterPropertiesSet() throwsException { 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 newIllegalStateException("Duplicate consumer configs: " + consumerConfig+ " and " + config); } consumerConfig =config; } } if (consumerConfig != null) { setConsumer(consumerConfig); } } } if (getApplication() == null && (getConsumer() ==null || getConsumer().getApplication() == null)) { Map<String,ApplicationConfig> applicationConfigMap = applicationContext == null ? null: BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext,ApplicationConfig.class, false, false); if (applicationConfigMap != null&& applicationConfigMap.size() > 0) { ApplicationConfigapplicationConfig = null; for (ApplicationConfig config :applicationConfigMap.values()) { if (config.isDefault() == null ||config.isDefault().booleanValue()) { if (applicationConfig!= null) { throw newIllegalStateException("Duplicate application configs: " +applicationConfig + " and " + config); } applicationConfig =config; } } if (applicationConfig != null){ 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 newIllegalStateException("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)) { 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) { 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 newIllegalStateException("Duplicate monitor configs: " + monitorConfig +" and " + config); } monitorConfig = config; } } if (monitorConfig != null) { setMonitor(monitorConfig); } } } Boolean b = isInit(); if (b == null && getConsumer()!= null) { b = getConsumer().isInit(); } if (b != null &&b.booleanValue()) { getObject(); } }
主要是按照默认的配置初始化了一些属性,最后调用了getObject()方法,获得代理类
getObject()方法:
public Object getObject() throws Exception { return get(); }
get()方法在ReferenceBean的父类com.alibaba.dubbo.config.ReferenceConfig中:
public synchronized T get() { if (this.destroyed) { throw new IllegalStateException("Alreadydestroyed!"); } if (this.ref == null) { init(); } return this.ref; }最后调用了init()方法:
private void init() { if (initialized) { return; } initialized = true; if (interfaceName == null ||interfaceName.length() == 0) { throw newIllegalStateException("<dubbo:reference interface=\"\" />interface not allow null!"); } // 获取消费者全局配置 checkDefault(); appendProperties(this); 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 newIllegalStateException(e.getMessage(), e); } checkInterfaceAndMethods(interfaceClass, methods); } String resolve =System.getProperty(interfaceName); String resolveFile = null; if (resolve == null || resolve.length()== 0) { resolveFile =System.getProperty("dubbo.resolve.file"); if (resolveFile == null ||resolveFile.length() == 0) { File userResolveFile = newFile(new File(System.getProperty("user.home")),"dubbo-resolve.properties"); if (userResolveFile.exists()) { resolveFile =userResolveFile.getAbsolutePath(); } } if (resolveFile != null &&resolveFile.length() > 0) { Properties properties = newProperties(); FileInputStream fis = null; try { fis = newFileInputStream(new File(resolveFile)); properties.load(fis); } catch (IOException e) { throw newIllegalStateException("Unload " + resolveFile + ", cause: "+ e.getMessage(), e); } finally { try { if (null != fis)fis.close(); } catch (IOException e) { logger.warn(e.getMessage(), e); } } resolve =properties.getProperty(interfaceName); } } if (resolve != null &&resolve.length() > 0) { url = resolve; if (logger.isWarnEnabled()) { if (resolveFile != null&& resolveFile.length() > 0) { logger.warn("Usingdefault dubbo resolve file " + resolveFile + " replace " +interfaceName + "" + resolve + " to p2p invoke remoteservice."); } else { logger.warn("Using -D"+ interfaceName + "=" + resolve + " to p2p invoke remoteservice."); } } } if (consumer != null) { if (application == null) { application =consumer.getApplication(); } if (module == null) { module = consumer.getModule(); } if (registries == null) { registries =consumer.getRegistries(); } if (monitor == null) { monitor =consumer.getMonitor(); } } if (module != null) { if (registries == null) { registries =module.getRegistries(); } if (monitor == null) { monitor = module.getMonitor(); } } if (application != null) { if (registries == null) { registries =application.getRegistries(); } if (monitor == null) { monitor = application.getMonitor(); } } checkApplication(); checkStubAndMock(interfaceClass); Map<String, String> map = newHashMap<String, String>(); Map<Object, Object> attributes =new HashMap<Object, Object>(); map.put(Constants.SIDE_KEY,Constants.CONSUMER_SIDE); map.put(Constants.DUBBO_VERSION_KEY,Version.getVersion()); map.put(Constants.TIMESTAMP_KEY,String.valueOf(System.currentTimeMillis())); if (ConfigUtils.getPid() > 0) { map.put(Constants.PID_KEY,String.valueOf(ConfigUtils.getPid())); } if (!isGeneric()) { String revision =Version.getVersion(interfaceClass, version); if (revision != null &&revision.length() > 0) { map.put("revision",revision); } String[] methods =Wrapper.getWrapper(interfaceClass).getMethodNames(); if (methods.length == 0) { logger.warn("NO methodfound in service interface " + interfaceClass.getName()); map.put("methods",Constants.ANY_VALUE); } else { map.put("methods",StringUtils.join(new HashSet<String>(Arrays.asList(methods)),",")); } } map.put(Constants.INTERFACE_KEY,interfaceName); appendParameters(map, application); appendParameters(map, module); appendParameters(map, consumer,Constants.DEFAULT_KEY); appendParameters(map, this); String prifix =StringUtils.getServiceKey(map); if (methods != null &&methods.size() > 0) { for (MethodConfig method : methods){ appendParameters(map, method,method.getName()); String retryKey =method.getName() + ".retry"; if (map.containsKey(retryKey)){ String retryValue =map.remove(retryKey); if("false".equals(retryValue)) { map.put(method.getName()+ ".retries", "0"); } } appendAttributes(attributes,method, prifix + "." + method.getName()); checkAndConvertImplicitConfig(method, map, attributes); } } //attributes经过系统context进行存储. StaticContext.getSystemContext().putAll(attributes); ref = createProxy(map); }init()方法把配置文件中的配置项通过判断和拼装,最后全放到了一个map中,最后调用createProxy()方法来生成代理类:
@SuppressWarnings({"unchecked","rawtypes", "deprecation"}) private T createProxy(Map<String,String> map) { URL tmpUrl = new URL("temp","localhost", 0, map); final boolean isJvmRefer; if (isInjvm() == null) { if (url != null &&url.length() > 0) { //指定URL的状况下,不作本地引用 isJvmRefer = false; } else if(InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) { //默认状况下若是本地有服务暴露,则引用本地服务. isJvmRefer = true; } else { isJvmRefer = false; } } else { isJvmRefer =isInjvm().booleanValue(); } if (isJvmRefer) { URL url = newURL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0,interfaceClass.getName()).addParameters(map); invoker = refprotocol.refer(interfaceClass,url); if (logger.isInfoEnabled()) { logger.info("Using injvmservice " + interfaceClass.getName()); } } else { if (url != null &&url.length() > 0) { // 用户指定URL,指定的URL多是对点对直连地址,也多是注册中心URL String[] us =Constants.SEMICOLON_SPLIT_PATTERN.split(url); if (us != null &&us.length > 0) { for (String u : us) { URL url =URL.valueOf(u); if (url.getPath() ==null || url.getPath().length() == 0) { url =url.setPath(interfaceName); } if(Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { urls.add(url.addParameterAndEncoded(Constants.REFER_KEY,StringUtils.toQueryString(map))); } else { urls.add(ClusterUtils.mergeUrl(url, map)); } } } } else { // 经过注册中心配置拼装URL List<URL> us =loadRegistries(false); if (us != null &&us.size() > 0) { for (URL u : us) { URL monitorUrl =loadMonitor(u); if (monitorUrl != null){ map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString())); } urls.add(u.addParameterAndEncoded(Constants.REFER_KEY,StringUtils.toQueryString(map))); } } if (urls == null || urls.size()== 0) { throw newIllegalStateException("No such any registry to reference " +interfaceName + " on the consumer " + NetUtils.getLocalHost() +" use dubbo version " + Version.getVersion() + ", please config<dubbo:registry address=\"...\" /> to your springconfig."); } } if (urls.size() == 1) { invoker =refprotocol.refer(interfaceClass, urls.get(0)); } else { List<Invoker<?>>invokers = new ArrayList<Invoker<?>>(); URL registryURL = null; for (URL url : urls) { invokers.add(refprotocol.refer(interfaceClass,url)); if(Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) { registryURL = url; // 用了最后一个registry url } } if (registryURL != null) { // 有 注册中心协议的URL // 对有注册中心的Cluster 只用AvailableCluster URL u =registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME); invoker = cluster.join(newStaticDirectory(u, invokers)); } else { // 不是 注册中心的URL invoker = cluster.join(newStaticDirectory(invokers)); } } } Boolean c = check; if (c == null && consumer != null){ c = consumer.isCheck(); } if (c == null) { c = true; // default true } if (c &&!invoker.isAvailable()) { throw newIllegalStateException("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()); } if (logger.isInfoEnabled()) { logger.info("Refer dubboservice " + interfaceClass.getName() + " from url " +invoker.getUrl()); } // 建立服务代理 return (T)proxyFactory.getProxy(invoker); }
createProxy()方法加载了和注册中心有关的配置,其中还区分了是不是本地jvm的服务,若是本地有服务,那就直接用本地的。
最后调用proxyFactory.getProxy(this.invoker)方法来生成代理类
proxyFactory是com.alibaba.dubbo.rpc.ProxyFactory接口的实现类,默认由com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory类来实现,他的getProxy()方法来自他的父类com.alibaba.dubbo.rpc.proxy.AbstractProxyFactory:
public <T> TgetProxy(Invoker<T> invoker) throws RpcException { Class<?>[] interfaces = null; String config = invoker.getUrl().getParameter("interfaces"); if (config != null &&config.length() > 0) { String[] types =Constants.COMMA_SPLIT_PATTERN.split(config); if (types != null &&types.length > 0) { interfaces = newClass<?>[types.length + 2]; interfaces[0] =invoker.getInterface(); interfaces[1] =EchoService.class; for (int i = 0; i <types.length; i++) { interfaces[i + 1] =ReflectUtils.forName(types[i]); } } } if (interfaces == null) { interfaces = newClass<?>[]{invoker.getInterface(), EchoService.class}; } return getProxy(invoker, interfaces); }
@SuppressWarnings("unchecked") public <T> TgetProxy(Invoker<T> invoker, Class<?>[] interfaces) { return (T)Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker)); }
public class OrderController { @Autowired private OrderService orderService; public void testDubboService() throws Exception{ orderService.selectByOrderId(); } }