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); } }