小编典典

从属性文件创建带有配置的未知数量的Bean

spring-boot

我的情况是我有一个属性文件来配置未知数量的bean:

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
:

我有一个配置类来读取这些属性:

@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。到目前为止,我尝试过的是

  1. 添加- @Bean方法并从中调用postConstruct()
@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()

  1. 一个BeanFactoryPostProcessor或一个BeanDefinitionRegistryPostProcessor。但是,这里我没有RssConfig从上面访问properties-file或-bean的权限,因为在生命周期中调用它太早了。

我需要做什么来生成那些动态数量的bean?我可能只有一步之遥了……我更喜欢Java配置解决方案而不是XML解决方案。


阅读 262

收藏
2020-05-30

共1个答案

小编典典

您需要注册的bean定义(不叫@Bean方法),所以BeanDefinitionRegistryPostProcessor还是ImportBeanDefinitionRegistrar要做到这一点目前最好的办法。您可以获取属性文件并使用PropertiesConfigurationFactory(在Spring
Boot中)而不是使用进行绑定@ConfigurationProperties,或者您可以使用父上下文或独立上下文SpringApplication来创建并绑定您RssConfig的bean定义注册代码。

2020-05-30