Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建参数化单例Springbean的基于Java的配置_Java_Spring_Inversion Of Control_Javabeans - Fatal编程技术网

创建参数化单例Springbean的基于Java的配置

创建参数化单例Springbean的基于Java的配置,java,spring,inversion-of-control,javabeans,Java,Spring,Inversion Of Control,Javabeans,我有以下XML形式的bean定义列表: <bean id="version201627" class="predicate.ClientVersionPredicate"> <property name="year" value="2016"/> <property name="week" value="27"/> </bean> <bean id="version201628" class="predicate.Clien

我有以下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

但是我可以在某个地方指定参数?谢谢。

这可以使用
BeanDefinitionRegistryPostProcessor
()和
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");
...

您可以使用
genericbeandefinition
(查看更多详细信息),这有助于动态定义和注册bean

下面的代码使用
genericbeandefinition
&帮助您在应用程序启动期间通过单个方法定义所需的bean

基本上,您需要一个包含年和周的对象列表(
List 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);
        }
    }
}

您可以使用外部化属性文件来包含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();
}

有没有办法让1个方法代替2个?我目前有20个XMLBean def,我更愿意将其简化为1个方法……对不起,我还没有看到这是您的主要观点。您真的需要不同的bean定义(每个bean都有一个唯一的id)还是一个具有不同初始化值的原型可以吗?我的错,我刚刚看到您在寻找单例Bean定义注册表后处理将是一条可行之路。。
version201627.year=2016
version201627.week=27

version201628.year=2016
version201628.week=28
@Bean
@ConfigurationProperties(prefix="version201627")
public ClientVersionPredicate version201627() {
    return new ClientVersionPredicate();
}

@Bean
@ConfigurationProperties(prefix="version201628")
public ClientVersionPredicate version201628() {
    return new ClientVersionPredicate();
}