Как внедрить простое значение

Примитив или строка обычно приходят не из DI по типу, а из конфигурации. Для одного значения подходит @Value, для группы — type-safe configuration properties.

@Value

@Component
final class Worker {
    private final int parallelism;
    private final Duration timeout;
 
    Worker(
            @Value("${worker.parallelism:4}") int parallelism,
            @Value("${worker.timeout:5s}") Duration timeout
    ) {
        if (parallelism < 1) {
            throw new IllegalArgumentException("parallelism must be positive");
        }
        this.parallelism = parallelism;
        this.timeout = timeout;
    }
}

${worker.parallelism:4} — property placeholder с default 4. Spring использует conversion service, поэтому строка из property source преобразуется в int или Duration.

#{...} — SpEL, то есть вычисляемое выражение. Для простой конфигурации лучше ${...}: меньше скрытой логики.

Группа настроек

@ConfigurationProperties("worker")
public record WorkerProperties(
        int parallelism,
        Duration timeout
) {}

Так проще валидировать, тестировать и видеть все параметры компонента. Класс нужно зарегистрировать через configuration-properties scanning или явное enable.

Откуда берётся значение

Spring Environment объединяет property sources: файлы конфигурации, environment variables, system properties и другие источники. Приоритет зависит от конкретной конфигурации Spring/Boot, поэтому итоговое значение полезно проверять через диагностический endpoint без публикации секрета.

Ошибки

  • field injection в static или final-поле;
  • default, который скрывает обязательную production-настройку;
  • секрет в исходнике или логах;
  • множество разрозненных @Value вместо одного объекта настроек;
  • считать строку "false" истинной по правилам Java — конверсию выполняет Spring по типу.

На собеседовании

Чем ${...} отличается от #{...}? Первое ищет property, второе вычисляет SpEL.

Как внедрить int? Например, constructor parameter с @Value, Spring преобразует строковое свойство.

Когда выбрать @ConfigurationProperties? Для связанной группы параметров, особенно с валидацией.

Почему constructor injection лучше field injection? Зависимость явна, объект можно сделать корректным сразу и проще тестировать.

Связано: Конфигурация и сборка Spring приложения, Spring Dependency Injection и Inversion of Control, Как заинжекить коллекцию.