
com.taobao.hsf.lightapi.ServiceFactory Maven / Gradle / Ivy
The newest version!
package com.taobao.hsf.lightapi;
import com.taobao.hsf.lightapi.report.LightApiReporter;
import com.taobao.hsf.lightapi.util.LightConstant;
import com.taobao.hsf.standalone.HSFEasyStarter;
import com.taobao.hsf.standalone.util.Constant;
import com.taobao.middleware.pandora.toolkit.SarFetcher;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 单例,可以在任何地方getInstance()来获得实例,并拿出对应的服务。
* Created by huangsheng.hs on 2014/10/25.
*/
public class ServiceFactory {
private static String sarPath = HSFEasyStarter.DEFAULT_RELEASE_PATH;
private static ConcurrentHashMap systemProps = new ConcurrentHashMap();
private static HashMap providers = new HashMap();
private static HashMap consumers = new HashMap();
private static volatile ServiceFactory factory;
private static LightApiReporter reporter = new LightApiReporter();
static {
System.out.println("LightApi is starting.");
}
private ServiceFactory() {
this(null);
}
private ServiceFactory(String id) {
this(id, -1, null);
}
private ServiceFactory(String id, String downloadURL) {
this(id, -1, downloadURL);
}
private ServiceFactory(String id, int port, String downloadURL) {
if (isPandoraInited()) {
LightConstant.pandoraInited = true;
} else {
startPandora(id, port, downloadURL);
LightConstant.pandoraInited = true;
}
reporter.doReport();
}
private void startPandora(String uniqueId, int port, String downloadURL) {
addJVMProperties();
String version = SarFetcher.getDefaultSarVersion();
if(version == null)
version = "";
if (downloadURL != null) {
Constant.perferDownloadUrl.set(downloadURL);
}
if (uniqueId == null) {
HSFEasyStarter.start(sarPath, version);
} else {
HSFEasyStarter.startWithVersionAndIdentifier(version, uniqueId, port);
}
}
/**
* 返回所有已经注册给LightApi的服务提供者
*
* @return
*/
public List providers() {
return new ArrayList(providers.values());
}
/**
* 返回所有通过LightApi消费的服务消费者
*
* @return
*/
public List consumers() {
return new ArrayList(consumers.values());
}
/**
* 获取一个HSF服务提供者实例,非HSFSpringProviderBean。
* 会缓存发布过的服务!
*
* @param id 一个服务的描述,通常取接口名,可以用此描述获得服务单例
* @return {@link ProviderService} 设置各个属性后,调用publish()方法来发布服务
*/
public synchronized ProviderService provider(String id) {
if (providers.get(id) == null) {
providers.put(id, new ProviderService().newProvider());
return providers.get(id);
} else {
return providers.get(id);
}
}
/**
* 获取一个HSF服务消费者实例,非HSFConsumerProviderBean。
* 会缓存消费过的服务!
*
* @param id 一个服务的描述,通常取接口名,可以用此描述获得服务单例
* @return {@link ConsumerService} 设置各个属性后,调用getInterface()方法来获得对应的接口
*/
public synchronized ConsumerService consumer(String id) {
if (consumers.get(id) == null) {
consumers.put(id, new ConsumerService().newConsumer());
return consumers.get(id);
} else {
if (!consumers.get(id).isConsumed()) {
throw new RuntimeException(LightConstant.NOT_CONS);
}
return consumers.get(id);
}
}
/**
* 下线服务并销毁对应的服务端实例
*
* @param id
*/
public synchronized void destroy(String id) {
ProviderService provider = providers.get(id);
if (provider != null) {
provider.offline();
clearProvider(id);
}
}
/**
* 仅仅remove掉所持有的consumer对象
* 无法注销configserver和diamond的订阅资源(受限于底层HSF未实现)
*
* @param id
*/
public synchronized void clearConsumer(String id) {
consumers.remove(id);
}
/**
* 请使用{@link this#destroy(String id)}方法
*
* @param id
*/
@Deprecated
public synchronized void clearProvider(String id) {
providers.remove(id);
}
/**
* 初始化LightApi和HSF资源,非多进程支持。多进程支持请使用带有id参数的重载方法,例如{@link #getInstance(String id)}
*
* @return
*/
public static synchronized ServiceFactory getInstance() {
return getInstance(null);
}
/**
* 初始化LightApi和HSF资源,多进程支持
*
* @param uniqueId 保证每个进程拥有不同的id
* @return
*/
public static synchronized ServiceFactory getInstance(String uniqueId) {
return getInstance(uniqueId, -1, null);
}
/**
* 初始化LightApi和HSF资源,多进程支持
*
* @param uniqueId 保证每个进程拥有不同的id
* @param port 指定端口号
* @return
*/
public static synchronized ServiceFactory getInstance(String uniqueId, int port) {
return getInstance(uniqueId, port, null);
}
/**
* 初始化LightApi和HSF资源,多进程支持
*
* @param uniqueId 保证每个进程拥有不同的id
* @param downloadURL 自定义的sar包下载路径,LightApi会从 downloadURL/taobao-hsf.tgz这个路径去下载sar包
* @return
*/
public static synchronized ServiceFactory getInstance(String uniqueId, String downloadURL) {
return getInstance(uniqueId, -1, downloadURL);
}
/**
* 初始化LightApi和HSF资源,多进程支持
*
* @param uniqueId 保证每个进程拥有不同的id
* @param port 指定端口号
* @param downloadURL 自定义的sar包下载路径
* @return
*/
public static synchronized ServiceFactory getInstance(String uniqueId, int port, String downloadURL) {
if (factory == null) {
factory = new ServiceFactory(uniqueId, port, downloadURL);
}
return factory;
}
/**
* 初始化LightApi和HSF资源,多进程支持
*
* @param sarPath sar包的绝对路径
* @return
*/
public static synchronized ServiceFactory getInstanceWithPath(String sarPath) {
ServiceFactory.sarPath = sarPath;
return getInstance();
}
/**
* 在Pandora容器启动之前放置系统参数
*
* @param key
* @param value
*/
public static void addJVMProperty(String key, String value) {
systemProps.put(key, value);
}
public static void addJVMProperty(Map props) {
systemProps.putAll(props);
}
private static boolean isPandoraInited() {
Class> HSFClazz;
try {
/**
* 为了判断Pandora是否已经启动,尝试初始化一个HSF的类,判断其classloader是否属于Pandora
* 这里初始化了GlobalRule这个类,会导致AppClassLoader下这个类可见,有隐患,而且不优雅,但绝大多数情况下,业务不会用到这个类
*/
HSFClazz = Class.forName("com.taobao.hsf.globalrule.GlobalRule", false,
ServiceFactory.class.getClassLoader());
} catch (ClassNotFoundException e) {
return false;
}
if (HSFClazz != null) {
String loader = HSFClazz.getClassLoader().getClass().getName().toLowerCase();
return loader.contains("pandora");
} else {
return false;
}
}
private static void addJVMProperties() {
for (Map.Entry propEntry : systemProps.entrySet()) {
System.setProperty(propEntry.getKey(), propEntry.getValue());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy