package org.skywalking.apm.agent.core.boot;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ServiceLoader;
/**
* The <code>ServiceManager</code> bases on {@link ServiceLoader},
* load all {@link BootService} implementations.
*
* @author wusheng
*/
public enum ServiceManager {
INSTANCE;
private static final ILog logger = LogManager.getLogger(StatusBootService.class);
private Map<Class, BootService> bootedServices = new HashMap<Class, BootService>();
public void boot() {
bootedServices = loadAllServices();
startup();
}
private Map<Class, BootService> loadAllServices() {
HashMap<Class, BootService> bootedServices = new HashMap<Class, BootService>();
Iterator<BootService> serviceIterator = load().iterator();
while (serviceIterator.hasNext()) {
BootService bootService = serviceIterator.next();
bootedServices.put(bootService.getClass(), bootService);
}
return bootedServices;
}
private void startup() {
for (BootService service : bootedServices.values()) {
try {
service.bootUp();
} catch (Throwable e) {
logger.error(e, "ServiceManager try to start [{}] fail.", service.getClass().getName());
}
}
}
/**
* Find a {@link BootService} implementation, which is already started.
*
* @param serviceClass class name.
* @param <T> {@link BootService} implementation class.
* @return {@link BootService} instance
*/
public <T extends BootService> T findService(Class<T> serviceClass) {
return (T) bootedServices.get(serviceClass);
}
ServiceLoader<BootService> load() {
return ServiceLoader.load(BootService.class);
}
}