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®istry=zookeeper×tamp=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×tamp=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");
}
}