2017-03-28 60 views
2

我有一個bean定義XML中的以下列表:基於Java的配置,創建參數辛格爾頓的Spring 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

這可以通過使用BeanDefinitionRegistryPostProcessorJavadoc)和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你如何定義你的配置值是由你(並根據您的實際的配置需求)。

豆子,現在可以通過名字來獲得:

ClientVersionPredicate version201627 = ctx.getBean("version201627"); 
ClientVersionPredicate version201628 = ctx.getBean("version201628"); 
... 
+0

有沒有一種方法,使1點的方法,而不是2?我目前有20個xml bean defs,我寧願把它簡化爲1個方法... – ssgao

+0

我還沒有看到這是你的主要觀點,對不起。你真的需要不同的bean定義(每個定義都有一個唯一的id),還是需要一個具有不同初始化值的原型? – boskoop

+0

我的不好,我剛剛看到你正在尋找單身。 :) Bean定義註冊表後處理將成爲當時的方式.. – boskoop

0

您可以使用GenericBeanDefintion(看here有詳細介紹),這有助於確定&動態註冊豆。

以下代碼使用GenericBeanDefintion &可幫助您在應用程序啓動期間通過單一方法定義所需的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 
} 
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(); 
}