使用运行时参数创建单例bean

时间:2014-03-29 18:43:04

标签: java spring dependency-injection

我是Spring框架的新手,无法找到实现以下目标的方法:

我正在使用一个类,其属性都是私有的,没有setter(使用该类对象的预期方法是使用构造函数设置属性一次) - 我将其称为 Preferences 。我还有一些类,每个类都有 Preferences 的相同实例作为属性。 首选项旨在包含某些属性,其中一些属性只能在运行时解析(例如由用户提供)。

在我的.xml文件中,我会写下以下内容:

<bean id="preferenes" class="Preferences" scope="singleton">
    <constructor-arg index="0" value="defaultAttrOne" />
    <constructor-arg index="1" value="defaultAttrTwo" />
    <constructor-arg index="2" value="defaultAttrThree" />
</bean>

<bean id="someOtherBean" class="SomeOtherClass" scope="singleton">
    <constructor-arg index="0" ref="preferences" />
</bean>

也就是说,我可以提供默认值,并在运行时将其中一些替换为自定义值。由于我无法修改 Preferences 的现有实例的属性,我将不得不构造一个新对象,并以某种方式使SomeOtherClass的实例指向该新对象(这可能通过bean机制吗?)。

相反,在实例化任何bean之前,我会将所需的运行时构造函数参数传递给 preferences bean(这些参数在第一次调用ApplicationContext之前就已知了#s; s构造函数)。我知道有一种getBean()方法可以将varargs作为初始化参数,尽管它只适用于原型bean。在这种情况下,我想初始化 Preferenes 一次,并让所有帮助类引用该单个实例。

感谢您的任何提示。

1 个答案:

答案 0 :(得分:0)

这几乎是Spring默认为你做的事情所以你没有什么特别的事情要做:如果你创建那个单例bean引用(称为preferences),你就会成为能够像你期望的那样将它注入任何其他bean。

关于使用默认值的属性,有几种方法可以实现:

常规XML配置

如果需要,可以保留纯粹基于XML的配置,并使用默认值配置PropertyPlaceholderConfigurer。类似的东西:

<bean class="org.s.beans.factory.config.PropertyPlaceholderConfigurer">      
    <property name="location" value="prefrences.properties"/>
</bean>

<bean id="preferenes" class="Preferences" scope="singleton">
   <constructor-arg index="0" value="$[preferences.one:12]" />
   <constructor-arg index="1" value="$[preferences.two:AUTO]" />
   <constructor-arg index="2" value="$[preferences.three:false]" />
</bean>

如果你不想要默认的

,那么在类路径的根处有一个prefrences.properties保留特定的值
prefrences.three=true

的FactoryBean

由于您已经在使用XML,因此可以使用FactoryBean来创建Preferences实例,例如

<bean id="preferences" class="org.myproject.PreferencesFactoryBean"/>

在工厂代码中,您可以使用任何机制来检索配置的非默认值,包括注入自定义属性。

Java config

您也可以使用java配置方式,但由于您是初学者,这可能会有所改变。但是,java配置非常强大且灵活,因此您可能需要尝试一下。

@Configuration
@PropertySource("classpath:preferences.properties")
public class AppConfig {

    @Value("${preferences.one}")
    private int preferenceOne = 12;

    @Value("${preferences.two}")
    private MyEnum preferenceTwo = MyEnum.AUTO;

    @Value("${preferences.three}")
    private boolean preferenceThree;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public Preferences preferences() {
        return new Preferences(preferenceOne, preferenceTwo, preferenceThree);
    }

}