#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
запускать мое приложение, а просто вызывать этот метод