You can combine the original answer with this answer about creating beans dynamically.
For example, let's say you create your own MailListProperties:
@ConfigurationProperties(prefix = "mail")
public record MailListProperties(Map<String, MailProperties> list) { }
Then you can create your own BeanDefinitionRegistryPostProcessor class to create the JavaMailSenderImpl beans:
public class DynamicMailsenderBeanDefinitionRegistrar implements BeanDefinitionRegistryPostProcessor {
private final MailListProperties properties;
public DynamicMailsenderBeanDefinitionRegistrar(Environment environment) {
this.properties = Binder
.get(environment)
.bind("mail", MailListProperties.class)
.orElseThrow(IllegalStateException::new);
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
properties.list().forEach((beanName, mailProperties) -> {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(JavaMailSenderImpl.class);
definition.setInstanceSupplier(() -> {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
sender.setHost(mailProperties.getHost());
// TODO: Here you put the logic to create a JavaMailSenderImpl
// You can read the properties defined in MailProperties
return sender;
});
registry.registerBeanDefinition(beanName, definition);
});
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
To register the DynamicMailsenderBeanDefinitionRegistrar bean, you can use the following code:
@Bean
public DynamicMailsenderBeanDefinitionRegistrar registrar(Environment environment) {
return new DynamicMailsenderBeanDefinitionRegistrar(environment);
}
To configure the properties, you can use the following properties file:
mail.list.first.host=...
mail.list.first.username=...
mail.list.first.password=...
mail.list.second.host=...
mail.list.second.username=...
mail.list.second.password=...
mail.list.third.host=...
mail.list.third.username=...
mail.list.third.password=...
In this example, the keys (first, second, and third) in the properties file will become the bean names. You can choose to autowire a specific JavaMailSenderImpl bean like this:
@Autowired
@Qualifier("first")
private JavaMailSenderImpl firstMailSender;
Alternatively, you can autowire all the beans of a specific type using a collection:
@Autowired
private List<JavaMailSenderImpl> mailSenders;