使用属性文件中的配置创建未知数量的 Bean [英] Creating Unknown Number of Beans With Configuration From Properties-Files
问题描述
我的情况是我有一个属性文件来配置未知数量的 bean:
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() {
}
}
这很好用.但是,现在我想基于此创建 bean.到目前为止我尝试过的是
This is working nicely. However, now I want to create beans based on that. What I've tried so far is
添加
@Bean
-methods 并从postConstruct()
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));
}
}
然而,Spring 尝试将参数自动连接到这些方法,而不是使用我在 postConstruct()
中提供的参数.
However, Spring tries to autowire the parameters to those methods rather than using the parameters I provided in postConstruct()
.
一个 BeanFactoryPostProcessor
或一个 BeanDefinitionRegistryPostProcessor
.但是,在这里我无法从上面访问属性文件或 RssConfig
-bean,因为它在生命周期的早期被调用.
a BeanFactoryPostProcessor
or a BeanDefinitionRegistryPostProcessor
. However, here I don't have access to the properties-file or the RssConfig
-bean from above as it's called too early in the lifecycle.
我需要做什么来生成那些动态数量的 bean?我可能只是一步之遥...我更喜欢 Java 配置解决方案而不是 XML 解决方案.
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.
推荐答案
需要注册bean定义(不是调用@Bean
方法),所以BeanDefinitionRegistryPostProcessor
或ImportBeanDefinitionRegistrar
是目前最好的方法.您可以获取属性文件并使用 PropertiesConfigurationFactory
(在 Spring Boot 中)而不是使用 @ConfigurationProperties
绑定到它,或者您可以使用父上下文或独立的 SpringApplication
在你的 bean 定义注册代码中创建和绑定你的 RssConfig
.
You need to register the bean definitions (not call @Bean
methods), so BeanDefinitionRegistryPostProcessor
or ImportBeanDefinitionRegistrar
are the best ways to do that currently. You can grab the properties file and bind to it using PropertiesConfigurationFactory
(in Spring Boot) instead of using @ConfigurationProperties
, or maybe you could use a parent context or a standalone SpringApplication
to create and bind your RssConfig
inside your bean definition registration code.
这篇关于使用属性文件中的配置创建未知数量的 Bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!