Не загружается компонент Spring bean при заданном определенном профиле
-
02-01-2020 - |
Вопрос
Предыстория: Итак, у меня есть несколько компонентов, которые взаимодействуют с внешними системами.Для разработки удобно имитировать внешние системы и заменять взаимодействующие компоненты некоторыми реализациями, которые выдают более или менее статичные ответы.Итак, что я делал, так это создавал интерфейс, реальную реализацию и заглушку, подобную этой:
public interface ExternalService {
// ...
}
@Service
public class ExternalServiceImpl implements ExternalService {
// ...
}
@Service
@Primary
@Profile({"stub"})
public class StubExternalService implements ExternalService {
// ...
}
... и это отлично работает:если профиль заглушки отсутствует, компонент-заглушка вообще не загружается.Если он присутствует, он прекрасно заменяет реальную реализацию из-за аннотации @Primary.
Проблема: Теперь, однако, я впервые столкнулся с ситуацией, когда у меня фактически есть две реальные реализации одного и того же интерфейса.Один из них определен как основной, но другой также может быть использован путем загрузки его из контекста приложения.
Я бы все еще хотел создать службу заглушек, чтобы заменить их оба, но на этот раз мой старый способ определения заглушки как @Primary не работает, потому что уже есть одна основная реализация.По сути, что мне было бы нужно, так это способ не загружать основной компонент, когда установлен профиль заглушки, но я не знаю, как именно это сделать.Поиск в Интернете или другие вопросы о переполнении стека, похоже, не помогают.
Решение
Оказывается, ответ был на удивление прост:вы добавляете не-оператор (!
) перед названием профиля:
@Service
@Primary
@Profile({"!stub"})
public class ExternalServiceImpl implements ExternalService {
// ...
}
Таким образом, компонент загружается только тогда, когда stub
-профиль не активен.Поддержка этой функции была добавлена в Пружина 3,2 М1.
Однако есть один нюанс:если вы напишете @Profile({"!stub", "foo"})
, запятая трактуется как "или", а не "и".Таким образом, этот пример bean будет активирован либо, если stub
не был активен , или если foo
был активен.
Редактировать/Добавлять: Весна 5.1 добавила поддержку для новый язык выражений для профилей: !stub & foo
активируется, когда stub
не активен и foo
активен.Большой успех!Вы даже можете смешивать и сочетать буквы "и" и " или" при условии, что вы используете круглые скобки: production & (us-east | eu-central)
.