由SOFARPC示例介绍基本流程和基础源码
1. Server
先看 Server 端测试方法:
public class QuickStartServer {
public static void main(String[] args) {
ServerConfig serverConfig = new ServerConfig()
.setProtocol("bolt") // 设置一个协议,默认bolt
.setPort(12200) // 设置一个端口,默认12200
.setDaemon(false); // 非守护线程
ProviderConfig<HelloService> providerConfig = new ProviderConfig<HelloService>()
.setInterfaceId(HelloService.class.getName()) // 指定接口
.setRef(new HelloServiceImpl()) // 指定实现
.setServer(serverConfig); // 指定服务端
providerConfig.export(); // 发布服务
}
}
在ProviderConfig
类中,获得一个服务提供者启动类,负责发布服务。
public synchronized void export() {
if (providerBootstrap == null) {
providerBootstrap = Bootstraps.from(this);
}
providerBootstrap.export();
}
com.alipay.sofa.rpc.bootstrap.Bootstraps#from(com.alipay.sofa.rpc.config.ProviderConfig)
这里看一下Bootstraps#from
方法,构造一个发布服务的包装类。
public static <T> ProviderBootstrap<T> from(ProviderConfig<T> providerConfig) {
String bootstrap = providerConfig.getBootstrap();
if (StringUtils.isEmpty(bootstrap)) {
// Use default provider bootstrap
bootstrap = RpcConfigs.getStringValue(RpcOptions.DEFAULT_PROVIDER_BOOTSTRAP);
providerConfig.setBootstrap(bootstrap);
}
ProviderBootstrap providerBootstrap = ExtensionLoaderFactory
.getExtensionLoader(ProviderBootstrap.class) // 从工厂拿到一个Loader
.getExtension(bootstrap, new Class[] {
ProviderConfig.class }, new Object[] {
providerConfig }); // 得到一个扩展实例
return (ProviderBootstrap<T>) providerBootstrap;
}
先学习一下ExtensionLoadeFactory
的工厂方法的写法:
/**
* All extension loader {Class : ExtensionLoader}
* ConcurrentHashMap
*/
private static final ConcurrentMap<Class, ExtensionLoader> LOADER_MAP = new ConcurrentHashMap<Class, ExtensionLoader>();
/**
* Get extension loader by extensible class with listener
*/
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> clazz, ExtensionLoaderListener<T> listener) {
ExtensionLoader<T> loader = LOADER_MAP.get(clazz);
if (loader == null) {
// a
synchronized (ExtensionLoaderFactory.class) {
loader = LOADER_MAP.get(clazz);
if (loader == null) {
loader = new ExtensionLoader<T>(clazz, listener); // b
LOADER_MAP.put(clazz, loader);
}
}
}
return loader;
}
/**
* Get extension loader by extensible class without listener
*/
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> clazz) {
return getExtensionLoader(clazz, null);
}
因为 b 处产生的 loader 一定在被初始化后才会被放进 map 中,所以不存在双重检查锁定的因指令重排导致的问题。
再看看获得实例的getExtension
方法:
public T getExtension(String alias, Class[] argTypes, Object[] args) {
ExtensionClass<T> extensionClass = getExtensionClass(alias);
if