My situation is that I have a properties-file to configure an unknown number of beans:
rssfeed.source[0]=http://feed.com/rss-news.xml
rssfeed.title[0]=Sample feed #1
rssfeed.source[1]=http://feed.com/rss-news2.xml
rssfeed.title[1]=Sample feed #2
:
I have a configuration class to read those properties:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "rssfeed", locations = "classpath:/config/rssfeed.properties")
public class RssConfig {
private List<String> source = new ArrayList<String>();
private List<String> title = new ArrayList<String>();
public List<String> getSource() {
return source;
}
public List<String> getTitle() {
return title;
}
@PostConstruct
public void postConstruct() {
}
}
This is working nicely. However, now I want to create beans based on that. What I've tried so far is
add
@Bean
-methods and call them frompostConstruct()
@Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public SourcePollingChannelAdapter createFeedChannelAdapter(int id, String url) { SourcePollingChannelAdapter channelAdapter = new SourcePollingChannelAdapter(); channelAdapter.setApplicationContext(applicationContext); channelAdapter.setBeanName("feedChannelAdapter" + id); channelAdapter.setSource(createMessageSource(id, url)); return channelAdapter; } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public FeedEntryMessageSource createMessageSource(int id, String url) { try { FeedEntryMessageSource messageSource = new FeedEntryMessageSource(new URL(url), ""); messageSource.setApplicationContext(applicationContext); messageSource.setBeanName("feedChannelAdapter" + id + ".source"); return messageSource; } catch (Throwable e) { Utility.throwAsUncheckedException(e); return null; } } @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public QueueChannel createFeedChannel(int id, String url) { QueueChannel channel = new QueueChannel(); channel.setApplicationContext(applicationContext); channel.setBeanName("feedChannel" + id); return channel; } @PostConstruct public void postConstruct() { for (int x = 0; x < source.size(); x++) { createFeedChannelAdapter(x, source.get(x)); } }
However, Spring tries to autowire the parameters to those methods rather than using the parameters I provided in
postConstruct()
.a
BeanFactoryPostProcessor
or aBeanDefinitionRegistryPostProcessor
. However, here I don't have access to the properties-file or theRssConfig
-bean from above as it's called too early in the lifecycle.
What do I need to do generate those dynamic number of beans? I'm probably just a tiny little step away... I prefer a Java configuration-solution over an XML-solution.