В каких сценариях может потребоваться создание объекта класса без использования Spring DI контейнера?

«В каких сценариях может потребоваться создание объекта класса без использования Spring DI контейнера?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Хотя Spring рекомендует управлять бинами через контейнер, существуют сценарии, где требуется прямое создание объектов:

1. Модульное тестирование (Unit Testing)

Цель: Проверка логики одного класса в изоляции. Пример: Создание экземпляра сервиса и передача в него mock-зависимостей с помощью Mockito.

// Тест без Spring Context
UserRepository mockRepo = Mockito.mock(UserRepository.class);
UserService service = new UserService(mockRepo); // Прямое создание
// ... вызов методов service и проверки

2. Утилитарные или статические классы

Цель: Классы, не требующие состояния или внедрения зависимостей (например, классы-хелперы, валидаторы).

public final class StringUtils {
    private StringUtils() {}
    public static boolean isEmpty(String str) { ... }
}
// Использование: StringUtils.isEmpty(text);

3. Интеграция с Legacy-кодом

Цель: Взаимодействие со старыми системами или библиотеками, которые не интегрированы в Spring Context.

4. Динамическое создание объектов через Reflection

Цель: Когда тип класса неизвестен на этапе компиляции.

String className = "com.example.LegacyService";
Class<?> clazz = Class.forName(className);
Object instance = clazz.getDeclaredConstructor().newInstance();

5. Создание DTO, Value Objects или сущностей JPA

Цель: Эти объекты обычно являются простыми носителями данных и создаются напрямую в бизнес-логике.

UserDto dto = new UserDto("John", "Doe");

Важно: Для сервисов с бизнес-логикой и зависимостями предпочтительным остается управление через Spring DI.