← Назад к вопросам

Что такое ServiceManager?

2.0 Middle🔥 201 комментариев
#Stream API и функциональное программирование#Многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое ServiceManager

ServiceManager — это класс в Java (из пакета android.content), который предоставляет доступ к системным сервисам на Android платформе. В контексте Java backend разработки, это понятие часто путают, но есть также Guava ServiceManager, который решает другую задачу — управление жизненным циклом сервисов в Java приложениях.

ServiceManager в Android

В Android, ServiceManager используется для получения системных сервисов:

import android.content.Context;
import android.content.Context.LAYOUT_INFLATER_SERVICE;
import android.app.ActivityManager;
import android.content.pm.PackageManager;

public class SystemServicesExample {
    public void accessSystemServices(Context context) {
        // Получаем различные системные сервисы
        ActivityManager activityManager = 
            (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        
        PackageManager packageManager = context.getPackageManager();
        
        // Используем полученные сервисы
        int memoryClass = activityManager.getMemoryClass();
    }
}

Guava ServiceManager (для Java backend)

Для Java разработчиков более полезен Guava ServiceManager, который управляет жизненным циклом управляемых сервисов (Service objects).

Основная концепция

Guava ServiceManager позволяет:

  • Запускать множество сервисов в правильном порядке
  • Управлять их жизненным циклом
  • Грациозно завершать их с учетом зависимостей
  • Отслеживать состояние каждого сервиса

Пример 1: Базовый Service

import com.google.common.util.concurrent.Service;
import com.google.common.util.concurrent.AbstractService;

// Кастомный сервис, наследуем AbstractService
public class DatabaseService extends AbstractService {
    private Connection connection;
    
    @Override
    protected void doStart() {
        try {
            // Инициализируем ресурсы при старте
            connection = DriverManager.getConnection("jdbc:mysql://localhost/mydb");
            System.out.println("Database connected");
            notifyStarted();  // Оповещаем об успешном старте
        } catch (SQLException e) {
            notifyFailed(e);  // Оповещаем об ошибке
        }
    }
    
    @Override
    protected void doStop() {
        try {
            // Закрываем ресурсы при остановке
            if (connection != null) {
                connection.close();
            }
            System.out.println("Database disconnected");
            notifyStopped();  // Оповещаем об остановке
        } catch (SQLException e) {
            notifyFailed(e);
        }
    }
    
    public Connection getConnection() {
        return connection;
    }
}

Пример 2: Несколько сервисов с зависимостями

import com.google.common.util.concurrent.AbstractService;
import com.google.common.util.concurrent.ServiceManager;
import com.google.common.util.concurrent.Service;
import java.util.concurrent.TimeUnit;

// Сервис инициализации кэша
public class CacheService extends AbstractService {
    private Map<String, Object> cache;
    
    @Override
    protected void doStart() {
        try {
            Thread.sleep(1000);  // Имитация инициализации
            cache = new ConcurrentHashMap<>();
            System.out.println("Cache service started");
            notifyStarted();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            notifyFailed(e);
        }
    }
    
    @Override
    protected void doStop() {
        cache.clear();
        System.out.println("Cache service stopped");
        notifyStopped();
    }
    
    public void put(String key, Object value) {
        cache.put(key, value);
    }
}

// Сервис обработки сообщений (зависит от CacheService)
public class MessageService extends AbstractService {
    private final CacheService cacheService;
    private ExecutorService executor;
    
    public MessageService(CacheService cacheService) {
        this.cacheService = cacheService;
    }
    
    @Override
    protected void doStart() {
        // MessageService может использовать CacheService
        executor = Executors.newFixedThreadPool(4);
        System.out.println("Message service started");
        notifyStarted();
    }
    
    @Override
    protected void doStop() {
        executor.shutdown();
        System.out.println("Message service stopped");
        notifyStopped();
    }
    
    public void processMessage(String message) {
        executor.submit(() -> {
            System.out.println("Processing: " + message);
            cacheService.put("last_message", message);
        });
    }
}

// Главное приложение с ServiceManager
public class Application {
    public static void main(String[] args) throws Exception {
        // Создаем сервисы
        CacheService cacheService = new CacheService();
        DatabaseService dbService = new DatabaseService();
        MessageService messageService = new MessageService(cacheService);
        
        // Создаем ServiceManager и передаем все сервисы
        ServiceManager serviceManager = new ServiceManager(
            Lists.newArrayList(
                cacheService,
                dbService,
                messageService
            )
        );
        
        // Регистрируем слушателя для отслеживания состояния
        serviceManager.addListener(new ServiceManager.Listener() {
            @Override
            public void healthy() {
                System.out.println("All services are healthy!");
            }
            
            @Override
            public void stopped() {
                System.out.println("All services have stopped");
            }
            
            @Override
            public void failure(Service service) {
                System.out.println("Service failed: " + service.getClass().getSimpleName());
            }
        });
        
        // Запускаем все сервисы
        serviceManager.startAsync();
        
        // Ждем, пока все сервисы успешно стартуют
        serviceManager.awaitHealthy(10, TimeUnit.SECONDS);
        System.out.println("Application started successfully");
        
        // Используем сервисы
        messageService.processMessage("Hello World");
        
        // Ждем время
        Thread.sleep(5000);
        
        // Грациозно завершаем все сервисы
        serviceManager.stopAsync();
        serviceManager.awaitStopped(10, TimeUnit.SECONDS);
        System.out.println("Application shut down");
    }
}

Состояния Service

NEW (создан, но не запущен)
  |
  v
STARTING (запуск в процессе)
  |
  v
RUNNING (работает)
  |
  v (либо stopAsync())
STOPPING (остановка в процессе)
  |
  v
TERMINATED (завершен)

  или в случае ошибки:
FAILED (произошла ошибка)

Пример 3: Проверка состояния сервисов

public class ServiceMonitoring {
    public static void main(String[] args) throws Exception {
        Service service = new DatabaseService();
        
        // Проверяем состояние
        System.out.println("State: " + service.state());  // NEW
        
        // Запускаем асинхронно
        service.startAsync();
        System.out.println("State: " + service.state());  // STARTING или RUNNING
        
        // Ждем запуска с таймаутом
        service.awaitRunning(5, TimeUnit.SECONDS);
        System.out.println("State: " + service.state());  // RUNNING
        
        // Проверяем, запущен ли
        if (service.isRunning()) {
            System.out.println("Service is running");
        }
        
        // Останавливаем
        service.stopAsync();
        System.out.println("State: " + service.state());  // STOPPING
        
        // Ждем остановки
        service.awaitTerminated(5, TimeUnit.SECONDS);
        System.out.println("State: " + service.state());  // TERMINATED
    }
}

Пример 4: Реальный кейс - Web сервер

import com.google.common.util.concurrent.AbstractService;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpExchange;
import java.net.InetSocketAddress;

public class WebService extends AbstractService {
    private HttpServer server;
    private final int port;
    
    public WebService(int port) {
        this.port = port;
    }
    
    @Override
    protected void doStart() {
        try {
            server = HttpServer.create(new InetSocketAddress(port), 0);
            
            // Регистрируем обработчик
            server.createContext("/", exchange -> {
                String response = "Hello from Web Service";
                exchange.sendResponseHeaders(200, response.length());
                exchange.getResponseBody().write(response.getBytes());
                exchange.close();
            });
            
            server.setExecutor(Executors.newFixedThreadPool(10));
            server.start();
            
            System.out.println("Web service started on port " + port);
            notifyStarted();
        } catch (Exception e) {
            notifyFailed(e);
        }
    }
    
    @Override
    protected void doStop() {
        if (server != null) {
            server.stop(0);
        }
        System.out.println("Web service stopped");
        notifyStopped();
    }
}

public class WebApplication {
    public static void main(String[] args) throws Exception {
        WebService webService = new WebService(8080);
        DatabaseService dbService = new DatabaseService();
        
        ServiceManager manager = new ServiceManager(
            Lists.newArrayList(dbService, webService)
        );
        
        manager.startAsync();
        manager.awaitHealthy();
        System.out.println("Web application started");
        
        // Приложение работает...
        Thread.sleep(60000);
        
        // Остановка
        manager.stopAsync();
        manager.awaitStopped();
    }
}

Обработка исключений

public class RobustService extends AbstractService {
    @Override
    protected void doStart() {
        try {
            // Инициализация
            notifyStarted();
        } catch (Exception e) {
            // Сервис не удалось запустить
            notifyFailed(e);
        }
    }
    
    @Override
    protected void doStop() {
        try {
            // Очистка ресурсов
            notifyStopped();
        } catch (Exception e) {
            // Ошибка при остановке
            notifyFailed(e);
        }
    }
}

public class ServiceApplication {
    public static void main(String[] args) {
        RobustService service = new RobustService();
        
        service.startAsync();
        
        try {
            service.awaitRunning(10, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            System.err.println("Service startup timeout");
        } catch (IllegalStateException e) {
            System.err.println("Service failed to start: " + e.getMessage());
        }
    }
}

Преимущества ServiceManager

  1. Управление жизненным циклом — автоматическое управление стартом и остановкой
  2. Синхронизация — ждем, пока все сервисы запустятся или остановятся
  3. Обработка ошибок — отслеживание сбоев сервисов
  4. Слушатели — реагирование на события сервисов
  5. Чистая архитектура — разделение ответственности между сервисами

Лучшие практики

// ХОРОШО: Простые, отдельные сервисы
public class LoggingService extends AbstractService { }
public class CacheService extends AbstractService { }
public class DatabaseService extends AbstractService { }

// ПЛОХО: Один монолитный сервис
public class EverythingService extends AbstractService {
    // Логирование, кэш, БД, сеть - все в одном
}

Заключение

ServiceManager (особенно Guava version) — это мощный инструмент для управления жизненным циклом компонентов в Java приложениях. Он предоставляет чистый и надежный способ запуска, остановки и мониторинга множества взаимозависимых сервисов, что критично для построения масштабируемых и надежных систем.
Что такое ServiceManager? | PrepBro