我在XML中有以下bean定义列表:
<bean id="version201627" class="predicate.ClientVersionPredicate">
<property name="year" value="2016"/>
<property name="week" value="27"/>
</bean>
<bean id="version201628" class="predicate.ClientVersionPredicate">
<property name="year" value="2016"/>
<property name="week" value="28"/>
</bean>
... // the list goes on
有没有办法将其转换为基于Java的@Configuration
,而不是创建这么多方法?
类似的东西:
@Bean
public ClientVersionPredicate somePredicate(String year, String week) {
return new ClientVersionPredicate(year, week);
}
但我可以在某处指定args吗?感谢。
答案 0 :(得分:0)
可以使用BeanDefinitionRegistryPostProcessor
(Javadoc)和BeanDefinitionBuilder
完成此操作。
@Component
public class ClientVersionPredicateDefiner implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// no need for post processing
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
IntStream.range(27, 47).forEach(week -> {
String year = "2016";
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(ClientVersionPredicate.class);
builder.addPropertyValue("year", year);
builder.addPropertyValue("week", String.valueOf(week));
registry.registerBeanDefinition("version" + year + week,
builder.getBeanDefinition());
});
}
}
对于此示例,我假设您在2016年需要一个版本27到46周。您如何定义配置值取决于您(并根据您的实际配置需求)。
现在可以通过名称获取bean:
ClientVersionPredicate version201627 = ctx.getBean("version201627");
ClientVersionPredicate version201628 = ctx.getBean("version201628");
...
答案 1 :(得分:0)
您可以使用GenericBeanDefintion
(查看here了解更多详情),这有助于定义&amp;动态注册bean。
以下代码使用GenericBeanDefintion
&amp;帮助您在应用程序启动期间通过单个方法定义所需的bean。
基本上,您需要一个包含数年和数周的对象列表(List<YearAndWeek> yearAndWeeks
),或者您可以使用包含数据和数据的任何其他集合/数组。然后迭代它以使用bean注册表注册bean。
@Component
public class MyProjectSpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
MyProjectSpringUtil.applicationContext = applicationContext;
}
@PostConstruct
public void addNewBeans() {
AutowireCapableBeanFactory factory =
applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
//Get your years and weeks data here through objects or array
List<YearAndWeek> yearAndWeeks = new ArrayList<>();
for(int i=0;i<yearAndWeeks.size();i++) {
YearAndWeek yearAndWeek = yearAndWeeks.get(i);
GenericBeanDefinition clientVersionPredicate =
new GenericBeanDefinition();
clientVersionPredicate.setBeanClass(ClientVersionPredicate.class);
clientVersionPredicate.setScope(
GenericBeanDefinition.SCOPE_SINGLETON);
MutablePropertyValues props = new MutablePropertyValues();
props.add("year", yearAndWeeks.getYear());
props.add("week", yearAndWeeks.getWeek());
clientVersionPredicate.setPropertyValues();
//register your bean with id & object
registry.registerBeanDefinition(
"version"+yearAndWeek,getYear()+yearAndWeek,getMonth(),
clientVersionPredicate);
}
}
}
YearAndWeek课程:
public class YearAndWeek {
private int year;
private int week;
//getters and setters
}
答案 2 :(得分:0)
您可以使用外部化属性文件来包含Bean的年和周值。属性的示例可能如下所示......
version201627.year=2016
version201627.week=27
version201628.year=2016
version201628.week=28
然后在你的java配置文件中,你可以这样做......
@Bean
@ConfigurationProperties(prefix="version201627")
public ClientVersionPredicate version201627() {
return new ClientVersionPredicate();
}
@Bean
@ConfigurationProperties(prefix="version201628")
public ClientVersionPredicate version201628() {
return new ClientVersionPredicate();
}