I have to create different messageSources programmatically and put them in a Bean in order to use the correct one when needed.
The application must have a messageSource for each of our Customers, so i created a Configuration class
@Configuration
public class MessageSourceConfig implements BeanFactoryAware {
private BeanFactory beanFactory;
@Autowired
private ICompanyService service;
private Map<Company, MessageSource> messageSourceMap = new HashMap<Company, MessageSource>();
// default messageSource
@Bean
@Primary
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@PostConstruct
public void onPostConstruct() {
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
Iterable<Company> companies = service.findAll();
for(Company c : companies) {
String beanName= c.getSlug()+"_messageSource";
MessageSource bean = getCompanyMessageSource(c);
configurableBeanFactory.registerSingleton(beanName, bean);
messageSourceMap.put(c, bean);
}
}
private MessageSource getCompanyMessageSource(Company company) {
ReloadableResourceBundleMessageSource ms = new ReloadableResourceBundleMessageSource();
ms.setBasename("classpath:" + company.getSlug() + "/messages");
ms.setUseCodeAsDefaultMessage(true);
ms.setCacheSeconds(5);
ms.setDefaultEncoding("UTF-8");
return ms;
}
public MessageSource companyMessageSource(Company company) {
return messageSourceMap.get(company);
}
In this way we have a default messageSource and one specific messageSource for each Company.
The idea was to put this specific messageSources into a Map and then accessing the correct one from the map when we need it.
The problem is that companyMessageSource
should be a bean, but i cannot pass a parameter to the bean, how can i access dynamically the correct source?
I am not entirely sure I understand how you want to use the created beans, but one way to get the registered singletons of MessageSource
is to get them programmatically something like this:
@Service
public class CompanyService {
@Autowired
private ApplicationContext applicationContext;
public void useCompanySpecificMessageSource(Company c) {
MessageSource ms = applicationContext.getBean(c.getSlug() + "_messageSource");
log.debug(ms.getMessage("code", null, new Locale("en", "GB"));
}
}
Hope this helps.