Выбор компонента по профилю и имени

#spring-boot

#весенняя загрузка

Вопрос:

У меня есть приложение, в которое будет внедрен FakeMailService, если я не в рабочей среде. Конфигурация следующая:

 @Bean
@Profile("prod")
public MailService mailService(JavaMailSender javaMailSender) {
    return new MailServiceImpl(javaMailSender);
}

@Bean
@ConditionalOnMissingBean(MailService.class)
public MailService fakeMailService() {
    return new FakeMailService();
}
  

Теперь мне нужно ввести que real MailServiceImpl в некоторых конкретных ситуациях, не заботясь об окружающей среде. Я предположил, что это может быть достигнуто с использованием квалифицированных компонентов, например:

 @Bean
@Profile("prod")
public MailService mailService(JavaMailSender javaMailSender) {
    return new MailServiceImpl(javaMailSender);
}

@Bean
@Qualifier("realMailService")
@ConditionalOnMissingBean(MailService.class)
public MailService forceRealMail(JavaMailSender javaMailSender) {
    return new MailServiceImpl(javaMailSender);
}

@Bean
@Primary
@ConditionalOnMissingBean(MailService.class)
public MailService fakeMailService() {
    return new FakeMailService();
}
  

И затем:

 class SomeService {
    @Autorwired @Qualifier("realMailService")
    MailService theRealMailService;
}

class OtherService {
    @Autorwired
    MailService fakeMailService;
}
  

Но кажется, что при этом реальный почтовый сервис (MailserviceImpl) будет вводиться постоянно, не имеет значения, использую ли я квалификатор или нет.

Я что-то упускаю? Есть ли какой-либо способ добиться этого?

Комментарии:

1. весенняя загрузка по умолчанию автоматически подключается с использованием типа. (т.е. IOC ищет зависимый компонент с типом в контексте. если он найден, он соединяется вместе.)

Ответ №1:

Решил это с помощью:

 @Bean
@Profile("prod")
public MailService mailService(JavaMailSender javaMailSender) {
    return new MailServiceImpl(javaMailSender);
}

@Bean
@Qualifier("realMailService")
@Profile("!prod")
public MailService realMailService(JavaMailSender javaMailSender) {
    return new MailServiceImpl(javaMailSender);
}

@Bean
@Primary
@Profile("!prod")
public MailService fakeMailService() {
    return new FakeMailService();
}