I need to configure a static field of a class when my application is booted, using objects obtained using dependency injection.
In particular, I have a class that manages notification channels, and that class should have some "default channels" to use, like the following:
public class CustomerNotificationPreference { static List<NotificationChannel> defaults = List.of(); Long id; List<NotificationChannel> channels; }
Everything works fine for non-static field, but I can't find a way to configure that defaults
using dependency injection.
What I've tried so far is the following:
@SpringBootApplication(scanBasePackages = {"com..."}) @EnableJpaRepositories("com...") public class MyApp { @Bean void configureDefaultChannel( TelegramBot telegramBot, JavaMailSender javaMailSender, @Value("${telegram-bot.default-chat}") String chatId, @Value("${mail.default-receiver}") String to ){ CustomerNotificationPreference.setDefaults(List.of( new TelegramNotificationChannel(telegramBot, chatId), new MailNotificationChannel(javaMailSender, to) )); } }
But obviously Spring doesn't allow this since a Bean must not be void (Invalid factory method 'configureDefaultChannel': needs to have a non-void return type!
)... are there ways to do this kind of things?
You can't autowire static field directly, but you can set static field after application is initialized using @PostConstruct
or catching 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
}
}