Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add Properties to an Application Context

Tags:

java

spring

I have a Standalone Application, this application calculates a value (Property) and then starts a Spring Context. My question is how can I add that calculated property to the spring context, so that I can use it like properties loaded from a property file (@Value("${myCalculatedProperty}"))?

To illustrate it a bit

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"/>

It is a Spring 3.0 Application.

like image 530
Ralph Avatar asked Feb 15 '12 13:02

Ralph


People also ask

Where do I put application properties?

You will need to add the application. properties file in your classpath. If you are using Maven or Gradle, you can just put the file under src/main/resources . If you are not using Maven or any other build tools, put that under your src folder and you should be fine.


Video Answer


3 Answers

In Spring 3.1 you can implement your own PropertySource, see: Spring 3.1 M1: Unified Property Management.

First, create your own PropertySource implementation:

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;
    }
}

Now add this PropertySource before refreshing the application context:

AbstractApplicationContext appContext =
    new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml"}, false
    );
appContext.getEnvironment().getPropertySources().addLast(
   new CustomPropertySource()
);
appContext.refresh();

From now on you can reference your new property in Spring:

<context:property-placeholder/>

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

Also works with annotations (remember to add <context:annotation-config/>):

@Value("${myCalculatedProperty}")
private String magic;

@PostConstruct
public void init() {
    System.out.println("Magic: " + magic);
}
like image 199
Tomasz Nurkiewicz Avatar answered Oct 17 '22 14:10

Tomasz Nurkiewicz


You can add the calculated value to the system properties:

System.setProperty("placeHolderName", myCalculatedProperty);
like image 27
Yazan Jaber Avatar answered Oct 17 '22 15:10

Yazan Jaber


If You are controlling the creation of ApplicationContext as in Your example than You can always add a BeanRegistryPostProcessor to add a second PropertyPlaceholderConfigurer into the context. It should have ignoreUnresolvablePlaceholders="true" and order="1" and resolve only the custom calculated properties using the Properties object. All other properties should be resolved by the PropertyPlaceholderConfigurer from the XML that should have order="2".

like image 3
Roadrunner Avatar answered Oct 17 '22 15:10

Roadrunner