Java 如何向应用程序上下文添加属性

Java 如何向应用程序上下文添加属性,java,spring,Java,Spring,我有一个独立的应用程序,这个应用程序计算一个值(属性),然后启动一个Spring上下文。 我的问题是如何将该计算属性添加到spring上下文中,以便像从属性文件(@Value(${myCalculatedProperty}”)加载的属性一样使用它 来说明一下 public static void main(final String[] args) { String myCalculatedProperty = magicFunction(); AbstractA

我有一个独立的应用程序,这个应用程序计算一个值(属性),然后启动一个Spring上下文。 我的问题是如何将该计算属性添加到spring上下文中,以便像从属性文件(
@Value(${myCalculatedProperty}”)
加载的属性一样使用它

来说明一下

public static void main(final String[] args) {
    String myCalculatedProperty = magicFunction();         
    AbstractApplicationContext appContext =
          new ClassPathXmlApplicationContext("applicationContext.xml");
    //How to add myCalculatedProperty to appContext (before starting the context)

    appContext.getBean(Process.class).start();
}
ApplicationContext.xml:

<bean id="propertyPlaceholderConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:*.properties" />
</bean>

<context:component-scan base-package="com.example.app"/>


这是一个Spring 3.0应用程序。

您的
myCalculatedProperty
必须包含在一个属性文件中(由Spring
PropertyPlaceHolderConfigure
注入)

编辑:只需使用setter,如下所示

public static void main(final String[] args) {
    String myCalculatedProperty = magicFunction();         
    AbstractApplicationContext appContext =
          new ClassPathXmlApplicationContext("applicationContext.xml");

    Process p = appContext.getBean(Process.class);
    p.setMyCalculatedProperty(myCalculatedProperty);
    p.start();
}

在Spring3.1中,您可以实现自己的
PropertySource
,请参阅:

首先,创建自己的
PropertySource
实现:

private static class CustomPropertySource extends PropertySource<String> {

    public CustomPropertySource() {super("custom");}

    @Override
    public String getProperty(String name) {
        if (name.equals("myCalculatedProperty")) {
            return magicFunction();  //you might cache it at will
        }
        return null;
    }
}
从现在起,您可以在Spring中引用新属性:

<context:property-placeholder/>

<bean class="com.example.Process">
    <constructor-arg value="${myCalculatedProperty}"/>
</bean>

可以将计算值添加到系统属性:

System.setProperty("placeHolderName", myCalculatedProperty);

如果您像示例中那样控制
ApplicationContext
的创建,则始终可以添加
BeanRegistryPostProcessor
以将第二个
PropertyPlaceHolderConfigure
添加到上下文中。它应该具有
ignoreunsolvablepholders=“true”
order=“1”
并使用
properties
对象仅解析自定义计算的属性。所有其他属性都应该由
propertyplaceholderconfigure
从应该具有
order=“2”

的XML解析,这将起作用,但我不想创建属性文件(应用程序每次运行的值都不相同),我想直接“注入”它们。只需使用属性的setter,没有?我不明白最后的评论。spring上下文中的属性与普通属性一样使用(使用@Value)。我需要在spring上下文中声明它,这样spring(PropertyPlaceholder)就可以像从属性文件加载属性一样使用它。我明白了,但这并不能解决问题。当我这样做时,我需要搜索所有用
@Value
注释的字段(其中一些是构造函数参数)。所以最后这会使spring过时。@Ralph:不,不幸的是。作为记录,我添加了完整的
PropertySource
示例实现。这实际上是可行的,但您必须确保您使用的是3.0之后的Spring版本(包括所有依赖项),否则您不会有太大进展。特别是检查context.xml文件顶部的包含内容。有人能给我建议spring引导的解决方案吗。@PratikShah从spring 3.1开始,您可以将
@PropertySource(“classpath:path/to/classpath/application.properties”)
添加到具有
@Configuration
的类中。复数
@propertySources
如果您使用的是Java,请注意,这样您就无法使用启动参数(即-DplaceHolderName=someEnvSpecificValue)从应用程序外部轻松重写此属性。我认为可以使用系统属性来处理特定于环境的值,还可以将自定义属性添加到上下文中,即注册多个
属性PlaceHolderConfigure
@Value("${myCalculatedProperty}")
private String magic;

@PostConstruct
public void init() {
    System.out.println("Magic: " + magic);
}
System.setProperty("placeHolderName", myCalculatedProperty);