Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.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
Java 使用运行时参数创建单例bean_Java_Spring_Dependency Injection - Fatal编程技术网

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

Java 使用运行时参数创建单例bean,java,spring,dependency-injection,Java,Spring,Dependency Injection,我是Spring框架的新手,无法找到实现以下目标的方法: 我使用的类的属性都是私有的,没有设置器。使用该类对象的预期方法是使用构造函数设置一次属性——我将其称为首选项。我还有几个类,每个类都具有与属性相同的首选项实例。首选项旨在包含某些属性,其中一些属性只能在运行时解析,例如由用户提供 在我的.xml文件中,我将写一些如下内容: <bean id="preferenes" class="Preferences" scope="singleton"> <construct

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

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

在我的.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>
也就是说,我可以提供默认值,并在运行时用自定义值替换其中的一些值。由于我无法修改现有首选项实例的属性,因此我必须构造一个新对象,并以某种方式使其他类的实例指向该新对象。这是否可以通过bean机制实现

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


谢谢您的提示。

这几乎就是Spring默认为您做的事情,因此您无需做任何特殊的事情:如果您创建名为preferences的单例bean引用,您将能够像您所期望的那样将其注入任何其他bean

对于具有默认值的属性,有几种方法可以实现这一点:

常规XML配置 如果需要,可以保留纯粹基于XML的配置,并使用默认值配置PropertyPlaceHolderConfigure。比如:

<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>
菜豆 由于您已经在使用XML,您可以使用一个创建Preferences实例的

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

使用属性解析。您介意再详细说明一下吗?使用属性占位符${somePropertyName}并配置PropertyPlaceHolderConfigure。然后在运行时添加属性,然后再刷新ApplicationContext。感谢您的帮助,尽管这还不是我的目标。我想传递给Preferences bean的参数不在属性文件中,可能是我在问题中误用了“属性”一词。相反,它们是在代码级别提供的,可以是一些自定义类的实例。按照注释约定,我将有一个@Value${myClass}注释的myClass myClass字段,由preferences bean使用,如上面的示例所示。在config类之外,我想先设置myClass字段,然后调用getBeanReferences.class。你不能这样做。这就像你想管理一个对象状态,然后让Spring来处理它。这就是为什么这样的东西通常是通过声明性的方式提供的,比如属性文件,因为容器管理它。也就是说,我上面提供给你的任何东西都没有问题。您可以创建FactoryBean并在getObject中拥有所需的所有逻辑。对于Java配置第三个示例,您可以调用首选项中需要的任何内容,并删除@Value字段
<bean id="preferences" class="org.myproject.PreferencesFactoryBean"/>
@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);
    }

}