Dubbo服务暴露(一) ------ ServiceBean源码解析

本文详细解析了Dubbo中的ServiceBean类如何在Spring启动时进行初始化,包括从Spring容器中获取并设置ProviderConfig、ProtocolConfig、ApplicationConfig等配置,以及在配置不全时的默认值填充。ServiceBean在初始化后会监听ContextRefreshedEvent事件,如果配置了非延迟发布,将在Spring启动后立即暴露服务。整个过程涉及多个配置类的属性设置、条件判断和方法调用,确保服务的正确暴露。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean,
	        ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware,
	        ApplicationEventPublisherAware {    
	//ProxyFactory$Adaptive       
	private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();  
	//Protocol$Adaptive 
	private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
	
	//先看到InitializingBean接口的afterPropertiesSet方法
	@Override
    public void afterPropertiesSet() throws Exception {
    	//如果在@Service注解中配置了provider的值,这里就能取到了,在ServiceAnnotationBeanPostProcessor 源码的文章已经看过了,注解的属性值被设置到BeanDefinition的PropertyValues中。
    	// 没有设置过provider配置类,设置provider配置类
        if (getProvider() == null) {
        	//从spring容器中获取ProviderConfig,可以拿不到,使用者只需要在配置文件 配置很少的必要的属性 就可以了。后续会使用默认的provider配置bean设置到ServiceBean中.
            Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
            //拿到了ProviderConfig
            if (providerConfigMap != null && providerConfigMap.size() > 0) {
            	//接着拿ProtocolConfig
                Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
                //ProtocolConfig也可以拿不到
                if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
                        && providerConfigMap.size() > 1) { // backward compatibility
                    List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
                    for (ProviderConfig config : providerConfigMap.values()) {     
                    	//有多个providerConfig ,找到配置default属性为true的那个
                        if (config.isDefault() != null && config.isDefault().booleanValue()) {
                            providerConfigs.add(config);
                        }
                    }  
                    //如果有default属性为true的providerConfig,设置到Provider配置类
                    if (!providerConfigs.isEmpty()) {
                        setProviders(providerConfigs);
                    }
                } 
                //获取到了ProtocolConfig 或者 只存在一个ProviderConfig
                else {
                    ProviderConfig providerConfig = null;
                    for (ProviderConfig config : providerConfigMap.values()) {
                        //没有配置default属性 或者 配置default属性为true
                        if (config.isDefault() == null || config.isDefault().booleanValue()) {
                        	//不允许有多个
                            if (providerConfig != null) {
                                throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
                            }
                            providerConfig = config;
                        }
                    }
                    //设置providerConfig
                    if (providerConfig != null) {
                        setProvider(providerConfig);
                    }
                }
            }
        }
        //没有设置过application,则获取application配置类
        if (getApplication() == null
                && (getProvider() == null || getProvider().getApplication() == null)) {
            //application正常来说都需要配置 , 需要有application.name属性
            Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
            //拿到了ApplicationConfig 
            if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
                ApplicationConfig applicationConfig = null;
                for (ApplicationConfig config : applicationConfigMap.values()) {
                	//没有配置default属性 或者 配置default属性为true
                    if (config.isDefault() == null || config.isDefault().booleanValue()) {
                    	//不允许有多个
                        if (applicationConfig != null) {
                            throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
                        }
                        applicationConfig = config;
                    }
                }
                //设置application配置类
                if (applicationConfig != null) {
                    setApplication(applicationConfig);
                }
            }
        }
        //下面都是一样的了,就不重复写注释了。module registry monitor protocols
        if (getModule() == null
                && (getProvider() == null || getProvider().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().isEmpty())
                && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
                && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
            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.isEmpty()) {
                    super.setRegistries(registryConfigs);
                }
            }
        }
        if (getMonitor() == null
                && (getProvider() == null || getProvider().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);
                }
            }
        }
        if ((getProtocols() == null || getProtocols().isEmpty())
                && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
            Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
                List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
                for (ProtocolConfig config : protocolConfigMap.values()) {
                    if (config.isDefault() == null || config.isDefault().booleanValue()) {
                        protocolConfigs.add(config);
                    }
                }
                if (protocolConfigs != null && !protocolConfigs.isEmpty()) {
                    super.setProtocols(protocolConfigs);
                }
            }
        }
        //设置path属性(服务暴露的地址)
        //如果没有配置path属性 , 且beanName的开头和接口名一致,则将path属性设置为beanName
        if (getPath() == null || getPath().length() == 0) {
            if (beanName != null && beanName.length() > 0
                    && getInterface() != null && getInterface().length() > 0
                    && beanName.startsWith(getInterface())) {
                setPath(beanName);
            }
        }
        //是否延迟发布
        if (!isDelay()) {
        	//非延迟发布,调用export
            export();
        }
    }
	
	private boolean isDelay() {
		//获取配置的delay属性
        Integer delay = getDelay();
        ProviderConfig provider = getProvider();
       	//没有配置delay 属性 ,则看providerConfig是否配置了delay属性
        if (delay == null && provider != null) {
            delay = provider.getDelay();
        }
       	//通常supportedApplicationListener为true(当不支持监听功能时,返回false) 如果delay不为空或者-1 则返回false
        return supportedApplicationListener && (delay == null || delay == -1);
    }
	@Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        SpringExtensionFactory.addApplicationContext(applicationContext);
        //设置监听器
        supportedApplicationListener = addApplicationListener(applicationContext, this);
    }
    //监听ContextRefreshedEvent 
	@Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
    	//延迟暴露且还没有暴露且不是不用暴露的
        if (isDelay() && !isExported() && !isUnexported()) {
            if (logger.isInfoEnabled()) {
                logger.info("The service ready on spring started. service: " + getInterface());
            }
            //进行服务暴露
            export();
        }
    }
    @Override
    public void export() {
    	//服务暴露,调用父类ServiceConfig的export方法
        super.export();
        //发布服务暴露事件(当该项目既有服务端又有消费端时,这里才有意义)
        publishExportEvent();
    }
}
public abstract class BeanFactoryUtils {
    public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) {
    	//设置监听器到spring容器中,spring发布事件时,会通知到各个监听器。
        try {
            // backward compatibility to spring 2.0.1
            Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class);
            method.invoke(applicationContext, listener);
            return true;
        } catch (Throwable t) {
            if (applicationContext instanceof AbstractApplicationContext) {
                try {
                    // backward compatibility to spring 2.0.1
                    Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class);
                    if (!method.isAccessible()) {
                        method.setAccessible(true);
                    }
                    method.invoke(applicationContext, listener);
                    return true;
                } catch (Throwable t2) {
                    // ignore
                }
            }
        }
        return false;
    }
}

ServiceConfig

	public synchronized void export() {
		//providerConfig可以没有值
        if (provider != null) {
        	//如果serviceConfig没有配置export delay 属性, 使用providerConfig的
            if (export == null) {
                export = provider.getExport();
            }
            if (delay == null) {
                delay = provider.getDelay();
            }
        }
        //export属性不为空 且 不为false(不需要服务暴露)
        if (export != null && !export) {
            return;
        }
		//延迟delay时间再去暴露
        if (delay != null && delay > 0) {
            delayExportExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    doExport();
                }
            }, delay, TimeUnit.MILLISECONDS);
        } 
        //直接暴露
        else {
            doExport();
        }
    }
	protected synchronized void doExport() {
		//不需要暴露,直接抛异常
        if (unexported) {
            throw new IllegalStateException("Already unexported!");
        }
        //已经暴露过直接返回
        if (exported) {
            return;
        }
        //exported修改为true , 表示服务开始暴露
        exported = true;
        if (interfaceName == null || interfaceName.length() == 0) {
            throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
        }
        //providerConfig初始化
        checkDefault();
        //一系列配置类的取值赋值
        if (provider != null) {
            if (application == null) {
                application = provider.getApplication();
            }
            if (module == null) {
                module = provider.getModule();
            }
            if (registries == null) {
                registries = provider.getRegistries();
            }
            if (monitor == null) {
                monitor = provider.getMonitor();
            }
            if (protocols == null) {
                protocols = provider.getProtocols();
            }
        }
        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();
            }
        }
        //暴露的类是否实现了GenericService接口
        if (ref instanceof GenericService) {
        	//interfaceClass 设置为 GenericService.class
            interfaceClass = GenericService.class;
            if (StringUtils.isEmpty(generic)) {
            	//generic修改为"true"
                generic = Boolean.TRUE.toString();
            }
        } 
        //没有实现GenericService接口
        else {
            try {
            	//对interfaceClass 赋值
                interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            //检查配置的@Service的methods属性  配置的方法需要有该接口的方法
            checkInterfaceAndMethods(interfaceClass, methods);
            //检查暴露的类是否为空 ,是否实现了interfaceClass 
            checkRef();
            generic = Boolean.FALSE.toString();
        }
        //这个就不看了,过时了,stub取代了local
        if (local != null) {
            if ("true".equals(local)) {
                local = interfaceName + "Local";
            }
            Class<?> localClass;
            try {
                localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
            }
        }
        //如果配置了stub属性
        if (stub != null) {
        	//配置的为true,修改stub为接口名称 + "Stub" (可以自己配置对应的实现类名称,不用这个默认的名字)
            if ("true".equals(stub)) {
                stub = interfaceName + "Stub";
            }
            Class<?> stubClass;
            try {
            	//检查stub对应的实现类是否存在
                stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e.getMessage(), e);
            }
            if (!interfaceClass.isAssignableFrom(stubClass)) {
                throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
            }
        }
        //对Application Registry Protocol进行属性填充 ,和checkDefault类似 限于篇幅不列了。
        checkApplication();
        checkRegistry();
        checkProtocol();
        //对ServiceConfig进行属性填充
        appendProperties(this);
        //检查stub
        checkStub(interfaceClass);
        //检查mock
        checkMock(interfaceClass);
        //如果path属性为空,设置为interfaceName
        if (path == null || path.length() == 0) {
            path = interfaceName;
        }
        doExportUrls();
        CodecSupport.addProviderSupportedSerialization(getUniqueServiceName(), getExportedUrls());
        ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
        ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
    }

check方法

	private void checkDefault() {
		//如果没有providerConfig,这里创建一个
        if (provider == null) {
            provider = new ProviderConfig();
        }
        //限于篇幅,不写出来。
        //这里就是给providerConfig的属性进行填充,循环所有set方法
        //从系统变量(System.getProperty) 和 配置文件中取值,反射调用方法设置值
        appendProperties(provider);
    }
    protected void checkInterfaceAndMethods(Class<?> interfaceClass, List<MethodConfig> methods) {
        if (interfaceClass == null) {
            throw new IllegalStateException("interface not allow null!");
        }
        if (!interfaceClass.isInterface()) {
            throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
        }
        //遍历配置的方法,至少有一个是interfaceClass中的方法
        if (methods != null && !methods.isEmpty()) {
            for (MethodConfig methodBean : methods) {
                String methodName = methodBean.getName();
                if (methodName == null || methodName.length() == 0) {
                    throw new IllegalStateException("<dubbo:method> name attribute is required! Please check: <dubbo:service interface=\"" + interfaceClass.getName() + "\" ... ><dubbo:method name=\"\" ... /></<dubbo:reference>");
                }
                boolean hasMethod = false;
                for (java.lang.reflect.Method method : interfaceClass.getMethods()) {
                    if (method.getName().equals(methodName)) {
                        hasMethod = true;
                        break;
                    }
                }
                if (!hasMethod) {
                    throw new IllegalStateException("The interface " + interfaceClass.getName()
                            + " not found method " + methodName);
                }
            }
        }
    }
    void checkStub(Class<?> interfaceClass) {
        if (ConfigUtils.isNotEmpty(local)) {
            Class<?> localClass = ConfigUtils.isDefault(local) ? ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
            }
            try {
                ReflectUtils.findConstructor(localClass, interfaceClass);
            } catch (NoSuchMethodException e) {
                throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
            }
        }
        //stub类必须要一个构造方法,该构造方法的入参为interfaceClass(用来持有ReferenceBean进行远程调用)
        if (ConfigUtils.isNotEmpty(stub)) {
            Class<?> localClass = ConfigUtils.isDefault(stub) ? ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
            }
            try {
                ReflectUtils.findConstructor(localClass, interfaceClass);
            } catch (NoSuchMethodException e) {
                throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
            }
        }
    }
    void checkMock(Class<?> interfaceClass) {
        if (ConfigUtils.isEmpty(mock)) {
            return;
        }
		//重新解析mock字符串的值
		/**
	     * <li>return => return null</li>
	     * <li>fail => default</li>
	     * <li>force => default</li>
	     * <li>fail:throw/return foo => throw/return foo</li>
	     * <li>force:throw/return foo => throw/return foo</li>
     	*/
        String normalizedMock = MockInvoker.normalizeMock(mock);
        //如果以return开头
        if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
        	//截取出return后面的值
            normalizedMock = normalizedMock.substring(Constants.RETURN_PREFIX.length()).trim();
            try {
            	//解析return的值
                MockInvoker.parseMockValue(normalizedMock);
            } catch (Exception e) {
                throw new IllegalStateException("Illegal mock return in <dubbo:service/reference ... " +
                        "mock=\"" + mock + "\" />");
            }
        } 
        //如果throw开头
        else if (normalizedMock.startsWith(Constants.THROW_PREFIX)) {
 			//截取出throw后面的值
            normalizedMock = normalizedMock.substring(Constants.THROW_PREFIX.length()).trim();
            if (ConfigUtils.isNotEmpty(normalizedMock)) {
                try {
                	//解析throw的值
                    MockInvoker.getThrowable(normalizedMock);
                } catch (Exception e) {
                    throw new IllegalStateException("Illegal mock throw in <dubbo:service/reference ... " +
                            "mock=\"" + mock + "\" />");
                }
            }
        } 
        //获取对应的mock类
        else {
            MockInvoker.getMockObject(normalizedMock, interfaceClass);
        }
    }
    public static Object parseMockValue(String mock, Type[] returnTypes) throws Exception {
        Object value = null;
        if ("empty".equals(mock)) {
            value = ReflectUtils.getEmptyObject(returnTypes != null && returnTypes.length > 0 ? (Class<?>) returnTypes[0] : null);
        } else if ("null".equals(mock)) {
            value = null;
        } else if ("true".equals(mock)) {
            value = true;
        } else if ("false".equals(mock)) {
            value = false;
        } 
        //截取调用单引号和双引号的转义符
        else if (mock.length() >= 2 && (mock.startsWith("\"") && mock.endsWith("\"")
                || mock.startsWith("\'") && mock.endsWith("\'"))) {
            value = mock.subSequence(1, mock.length() - 1);
        } else if (returnTypes != null && returnTypes.length > 0 && returnTypes[0] == String.class) {
            value = mock;
        } 
        //数字 json 数组 需要用到 com.alibaba.fastjson.JSON
        else if (StringUtils.isNumeric(mock)) {
            value = JSON.parse(mock);
        } else if (mock.startsWith("{")) {
            value = JSON.parseObject(mock, Map.class);
        } else if (mock.startsWith("[")) {
            value = JSON.parseObject(mock, List.class);
        } else {
            value = mock;
        }
        if (returnTypes != null && returnTypes.length > 0) {
            value = PojoUtils.realize(value, (Class<?>) returnTypes[0], returnTypes.length > 1 ? returnTypes[1] : null);
        }
        return value;
    }
    public static Throwable getThrowable(String throwstr) {
    	//从throwables中获取 ,第一次的化获取不到
        Throwable throwable = throwables.get(throwstr);
        if (throwable != null) {
            return throwable;
        }
        try {
            Throwable t;
            //根据throwstr获取到异常对象
            Class<?> bizException = ReflectUtils.forName(throwstr);
            Constructor<?> constructor;
            //实例化异常对象,该异常对象需要有String入参类型的构造函数
            constructor = ReflectUtils.findConstructor(bizException, String.class);
            t = (Throwable) constructor.newInstance(new Object[]{"mocked exception for service degradation."});
            if (throwables.size() < 1000) {
                throwables.put(throwstr, t);
            }
            return t;
        } catch (Exception e) {
            throw new RpcException("mock throw error :" + throwstr + " argument error.", e);
        }
    }
    public static Object getMockObject(String mockService, Class serviceType) {
    	//如果配置的为 "true"或者"default" 则mockService为接口类型+"Mock"
        if (ConfigUtils.isDefault(mockService)) {
            mockService = serviceType.getName() + "Mock";
        }
		//获取mock类
        Class<?> mockClass = ReflectUtils.forName(mockService);
        //需要实现ServieBean对应的接口
        if (!serviceType.isAssignableFrom(mockClass)) {
            throw new IllegalStateException("The mock class " + mockClass.getName() +
                    " not implement interface " + serviceType.getName());
        }
		//实例化mock类,需要无参构造函数
        try {
            return mockClass.newInstance();
        } catch (InstantiationException e) {
            throw new IllegalStateException("No default constructor from mock class " + mockClass.getName(), e);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
    }

doExportUrls

	private void doExportUrls() {
		//根据配置类的属性,拼接出注册中心的url,比如(registry://127.0.0.1:2181/com.alibaba.dubbo.registry.RegistryService?application=dubbo_provider&dubbo=2.0.2&owner=world&pid=22012&registry=zookeeper&timestamp=1627634496119)
        List<URL> registryURLs = loadRegistries(true);
        //循环所有的protocols,默认只有一个dubbo的协议
        for (ProtocolConfig protocolConfig : protocols) {
        	//由协议形成最终的url 默认的dubbo协议如下 
        	//dubbo://10.2.91.161:20880/test.dubbo.service.TestService?anyhost=true&application=dubbo_provider&bean.name=ServiceBean:test.dubbo.service.TestService&bind.ip=10.2.91.161&bind.port=20880&dubbo=2.0.2&generic=false&interface=test.dubbo.service.TestService&methods=test1,test2&owner=world&pid=21480&revision=0.0.1-SNAPSHOT&side=provider&timestamp=1627636849139
            doExportUrlsFor1Protocol(protocolConfig, registryURLs);
        }
    }
    protected List<URL> loadRegistries(boolean provider) {
        checkRegistry();
        List<URL> registryList = new ArrayList<URL>();
        if (registries != null && !registries.isEmpty()) {
            for (RegistryConfig config : registries) {
            	//获取注册中心的地址
                String address = config.getAddress();
                if (address == null || address.length() == 0) {
                	//默认0.0.0.0
                    address = Constants.ANYHOST_VALUE;
                }
                //从系统变量中获取赋值给address 
                String sysaddress = System.getProperty("dubbo.registry.address");
                if (sysaddress != null && sysaddress.length() > 0) {
                    address = sysaddress;
                }
                if (address.length() > 0 && !RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
                    Map<String, String> map = new HashMap<String, String>();
                    //限于篇幅appendParameters方法不写了
                    //将application配置类的属性添加到map,@Parameter的excluded属性可以用来排除不需要的属性
                    appendParameters(map, application);
                    //将registry配置类的属性添加到map
                    appendParameters(map, config); 
                    //注册中心路径
                    map.put("path", RegistryService.class.getName());
                    //版本
                    map.put("dubbo", Version.getProtocolVersion());
                    //时间
                    map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
                    if (ConfigUtils.getPid() > 0) {
                        map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
                    }
                    //没有配置ProtocolConfig
                    if (!map.containsKey("protocol")) {
                        if (ExtensionLoader.getExtensionLoader(RegistryFactory.class).hasExtension("remote")) {
                            map.put("protocol", "remote");
                        } else {
                        	//protocol默认为dubbo
                            map.put("protocol", "dubbo");
                        }
                    }
                    //将注册中心地址和map内容拼接成url
                    List<URL> urls = UrlUtils.parseURLs(address, map);
                    for (URL url : urls) {
                    	//添加注册中心的类型的参数
                        url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
                        //协议头修改从注册中心的类型修改为registry
                        url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
                        if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
                                || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
                            registryList.add(url);
                        }
                    }
                }
            }
        }
        return registryList;
    }

doExportUrlsFor1Protocol

 private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
        String name = protocolConfig.getName();
        if (name == null || name.length() == 0) {
            name = "dubbo";
        }

        Map<String, String> map = new HashMap<String, String>();
        //生产者
        map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
        //版本号
        map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
        //时间戳
        map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
        if (ConfigUtils.getPid() > 0) {
            map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
        }
        //将配置类的属性添加到map中
        appendParameters(map, application);
        appendParameters(map, module);
        appendParameters(map, provider, Constants.DEFAULT_KEY);
        appendParameters(map, protocolConfig);
        appendParameters(map, this);
        //ServiceBean配置了methods 属性
        if (methods != null && !methods.isEmpty()) {
        	//每一个@Method注解对应一个MethodConfig 
            for (MethodConfig method : methods) {
            	//MethodConfig 属性放入map中
                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");
                    }
                }
                //获取配置的Method注解的Arguments注解
                List<ArgumentConfig> arguments = method.getArguments();
                if (arguments != null && !arguments.isEmpty()) {
                    for (ArgumentConfig argument : arguments) {
                       	//如果配置的方法入参的类型
                        if (argument.getType() != null && argument.getType().length() > 0) {
                        	//获取接口所有的方法
                            Method[] methods = interfaceClass.getMethods();
                            if (methods != null && methods.length > 0) {
                                for (int i = 0; i < methods.length; i++) {
                                    String methodName = methods[i].getName();
                                    //找到注解配置的方法
                                    if (methodName.equals(method.getName())) {
                                        Class<?>[] argtypes = methods[i].getParameterTypes();
                                        //如果配置了入参的下标
                                        if (argument.getIndex() != -1) {
                                        	//判断接口方法对应位置的入参和配置的入参类型是否一致
                                        	//不一致则抛异常
                                        	//一致则将ArgumentConfig的字段和值 填充到 map 中
                                            if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {
                                                appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                                            } else {
                                                throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
                                            }
                                        } 
                                        //没有配置入参的下标
                                        else {
                                            //循环所有方法入参进行匹配
                                            for (int j = 0; j < argtypes.length; j++) {
                                                Class<?> argclazz = argtypes[j];
                                                if (argclazz.getName().equals(argument.getType())) {
                                                    appendParameters(map, argument, method.getName() + "." + j);
                                                    //找不到则抛异常
                                                    if (argument.getIndex() != -1 && argument.getIndex() != j) {
                                                        throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + argument.getType());
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } 
                        //只配置了方法入参的下标
                        else if (argument.getIndex() != -1) {
                            appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                        } else {
                            throw new IllegalArgumentException("argument config must set index or type attribute.eg: <dubbo:argument index='0' .../> or <dubbo:argument type=xxx .../>");
                        }

                    }
                }
            } // end of methods for
        }
		//如果generic是否为true,添加相应的参数
        if (ProtocolUtils.isGeneric(generic)) {
            map.put(Constants.GENERIC_KEY, generic);
            map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
        } else {
        	//设置version属性
            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 method found in service interface " + interfaceClass.getName());
                map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
            } 
            else {
                map.put(Constants.METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
            }
        }
        //是否配置了token值
        if (!ConfigUtils.isEmpty(token)) {
        	//配置的值"true"或者"default", 则token随机生成uuid。
            if (ConfigUtils.isDefault(token)) {
                map.put(Constants.TOKEN_KEY, UUID.randomUUID().toString());
            } else {
                map.put(Constants.TOKEN_KEY, token);
            }
        }
        //ProtocolConfig的配置name的值是否是为LOCAL_PROTOCOL("injvm")(本机使用),则不用注册,也不用通知其他消费者
        if (Constants.LOCAL_PROTOCOL.equals(protocolConfig.getName())) {
            protocolConfig.setRegister(false);
            map.put("notify", "false");
        }
        //http协议才需要使用,dubbo协议可以不配置
        String contextPath = protocolConfig.getContextpath();
        if ((contextPath == null || contextPath.length() == 0) && provider != null) {
            contextPath = provider.getContextpath();
        }
		//获取ip和端口
        String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
        Integer port = this.findConfigedPorts(protocolConfig, name, map);
        //构建url对象
        URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
		//可以基于spi构建自定义的url
        if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                .hasExtension(url.getProtocol())) {
            url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)
                    .getExtension(url.getProtocol()).getConfigurator(url).configure(url);
        }
		//配置了scope属性且值不为SCOPE_NONE
        String scope = url.getParameter(Constants.SCOPE_KEY);
        if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
			//scope值的值不为remote,则需要本机暴露(injvm)
            if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
                exportLocal(url);
            }
            //scope值的值不为injvm,则需要供远程调用
            if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {
                if (logger.isInfoEnabled()) {
                    logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
                }
                if (registryURLs != null && !registryURLs.isEmpty()) {
                    for (URL registryURL : registryURLs) {
                        url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));
                        //将MonitorConfig的相关属性值加入到url中 (监控配置后文再细说)
                        URL monitorUrl = loadMonitor(registryURL);
                        if (monitorUrl != null) {
                            url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());
                        }
                        if (logger.isInfoEnabled()) {
                            logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
                        }
						//如果配置proxy属性。在url中添加该属性,用于自定生成代理对象
                        String proxy = url.getParameter(Constants.PROXY_KEY);
                        if (StringUtils.isNotEmpty(proxy)) {
                            registryURL = registryURL.addParameter(Constants.PROXY_KEY, proxy);
                        }
						
						//生成Invoker代理对象,最终用来调用目标方法。限于篇幅后文再来看
                        Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));
                        //再对Invoker做一层包装,持有Invoker对象和this(ServiceConfig)
                        DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
						//服务暴露 限于篇幅后文再来看
                        Exporter<?> exporter = protocol.export(wrapperInvoker);
                        exporters.add(exporter);
                    }
                }
                else {
                    Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
                    DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);

                    Exporter<?> exporter = protocol.export(wrapperInvoker);
                    exporters.add(exporter);
                }
            }
        }
        this.urls.add(url);
    }
    private void exportLocal(URL url) {
    	//构建本地暴露的url
        if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
            URL local = URL.valueOf(url.toFullString())
            		//Protocol设置为LOCAL_PROTOCOL("injvm")
                    .setProtocol(Constants.LOCAL_PROTOCOL)
                    //host为127.0.0.1
                    .setHost(LOCALHOST)
                    .setPort(0);
            StaticContext.getContext(Constants.SERVICE_IMPL_CLASS).put(url.getServiceKey(), getServiceClass(ref));
            //这个后续文章再来分析
            Exporter<?> exporter = protocol.export(
                    proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
            //将本地暴露的服务加入到exporters中
            exporters.add(exporter);
            logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值