Я кодирую библиотеку и сервис, использующий эту библиотеку.Я хочу иметь сервис UsernameProvider
, который позаботится о извлечении имени пользователя вошедшего в систему пользователя.Я использую службу в самой библиотеке:
class AuditService {
@Autowired
UsernameProvider usernameProvider;
void logChange() {
String username = usernameProvider.getUsername();
...
}
}
Я хочу иметь реализацию по умолчанию интерфейса UsernameProvider
, которая извлекает имя пользователя из субъектного утверждения JWT.Однако в сервисе, который зависит от библиотеки, я хочу использовать обычную аутентификацию, поэтому я бы создал BasicAuthUsernameProvider
, который переопределяет getUsername()
.
Естественно, я получаю сообщение об ошибке, когда есть несколько кандидатов на автоматическое подключение одного и того же типа (DefaultUsernameProvider
в библиотеке и BasicAuthUsernameProvider
в службе), поэтому мне придется пометить компонент в службекак @Primary
.Но я не хочу, чтобы клиенты библиотеки указывали основной компонент, а вместо этого отмечали значение по умолчанию.
Добавление @Order(value = Ordered.LOWEST_PRECEDENCE)
в DefaultUsernameProvider
не работало.
Добавление @ConditionalOnMissingBean
в классе конфигурации в библиотеке тоже не работал.
EDIT: Оказывается, добавление @Component
в UsernameProvider
классы реализации делает @ConditionalOnMissingBean
бесполезным, так какSpring Boot пытается автоматически связать каждый класс, аннотированный как Компонент, поэтому выдает исключение «Несколько бинов типа найдено» .