Настройте статическое поле при загрузке с помощью пружины внедрения зависимостей

#java #spring-boot #dependency-injection #javabeans

Вопрос:

Мне нужно настроить статическое поле класса при загрузке моего приложения, используя объекты, полученные с помощью внедрения зависимостей.
В частности, у меня есть класс, который управляет каналами уведомлений, и у этого класса должны быть некоторые «каналы по умолчанию» для использования, например, следующие:

общедоступный класс CustomerNotificationPreference {
статический список<Канал уведомлений> по умолчанию = List.of();
 Длинный идентификатор;
 Список каналов<Канал уведомления> ;
}

Все отлично работает для нестатического поля, но я не могу найти способ настроить это defaults с помощью внедрения зависимостей.

Что я пробовал до сих пор, так это следующее:

@SpringBootApplication(пакеты сканирования = {"com..."})
@EnableJpaRepositories("com...")
общедоступный класс MyApp {

 @Bean
void сконфигурированный канал(
 Телеграм-бот Телеграм-бот,
JavaMailSender javaMailSender,
@Значение("${telegram-бот.чат по умолчанию}") Строка chatId,
@Значение("${mail.по умолчанию-получатель}") Строка для
 ){
 CustomerNotificationPreference.setDefaults(Список.из(
новый канал телеграмнотификации(телеграм-бот, чат),
новый канал почтовой рассылки(javaMailSender, кому)
 ));
 }

}

Но, очевидно, Весна этого не допускает, так как боб не должен быть пустым ( Invalid factory method 'configureDefaultChannel': needs to have a non-void return type! )… есть ли способы делать такие вещи?

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

1. @PostConstruct вместо @Bean этого ?

2. @Alex, насколько я знаю, это не позволяет иметь параметры

3. Мы работаем с полевой инъекцией, но id, возможно, если есть способы вводить непосредственно в параметры, будет оценен

4. Зачем вам это нужно как статичное? Я думаю, что было бы лучше зарегистрировать его как сервис и внедрить в него каналы через DI

5. @Alex, потому что этот класс будет построен с использованием Джексона, и поэтому DI не будет работать

Ответ №1:

Вы не можете автоматически подключить статическое поле напрямую, но вы можете установить статическое поле после инициализации приложения с помощью @PostConstruct или перехвата ApplicationReadyEvent

 public class MyApp {

    @Autowired
    TelegramBot telegramBot;

    @Autowired
    JavaMailSender javaMailSender

    @Value("${telegram-bot.default-chat}")
    String chatId;

    @Value("${mail.default-receiver}") 
    String to;

    @PostConstruct
    void setDefaults() {
        CustomerNotificationPreference.setDefaults(List.of(
            new TelegramNotificationChannel(telegramBot, chatId),
            new MailNotificationChannel(javaMailSender, to)
        ));
    }

    // OR

    @EventListener(ApplicationReadyEvent::class)
    void setDefaults() { 
        // same code as above
    }
    
} 
 

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

1. прежде всего, спасибо вам за то, что уделили мне время… но это то, что я уже использую, как вы можете видеть из раздела комментариев… то, что я искал, — это что-то вроде контроллера, где вы можете вводить значения в список параметров, чтобы сделать код более проверяемым, так как мне не нужно telegramBot и javaMailSender запускать мое приложение, а просто вызывать этот метод