Marty Pitt
Marty Pitt

Reputation: 29280

Dynamically accessing properties using Spring 3.1's property abstraction

I'm trying to dynamically access properties from Spring's Environment property abstraction.

I declare my property files like this:

<context:property-placeholder
    location="classpath:server.common.properties,
    classpath:server.${my-environment}.properties" />

In my property file server.test.properties, I define the following:

myKey=foo

Then, given the following code:

@Component
public class PropertyTest {
    @Value("${myKey}")
    private String propertyValue;

    @Autowired 
    private PropertyResolver propertyResolver;

    public function test() {
         String fromResolver = propertyResolver.getProperty("myKey");
    }
}

When I run this code, I end up with propertyValue='foo', but fromResolver=null;

Receiving propertyValue indicates that the properties are being read, (and I know this from other parts of my code). However, attempting to look them up dynamically is failing.

Why? How can I dynamically look up property values, without having to use @Value?

Upvotes: 4

Views: 5340

Answers (2)

Marty Pitt
Marty Pitt

Reputation: 29280

To get this to work I had to split out the reading of the properties into a @Configuration bean, as shown here.

Here's the complete example:

@Configuration
@PropertySource("classpath:/server.${env}.properties")
public class AngularEnvironmentModuleConfiguration  {

    private static final String PROPERTY_LIST_NAME = "angular.environment.properties";

    @Autowired
    private Environment environment;

    @Bean(name="angularEnvironmentProperties")
    public Map<String,String> getAngularEnvironmentProperties()
    {
        String propertiesToInclude = environment.getProperty(PROPERTY_LIST_NAME, "");
        String[] propertyNames = StringUtils.split(propertiesToInclude, ",");

        Map<String,String> properties = Maps.newHashMap();
        for (String propertyName : propertyNames)
        {
            String propertyValue = environment.getProperty(propertyName);
            properties.put(propertyName, propertyValue);
        }

        return properties;
    }
}

The set of properties are then injected elsewhere, to be consumed.

Upvotes: 1

Ryan Stewart
Ryan Stewart

Reputation: 128779

Simply adding a <context:property-placeholder/> doesn't add a new PropertySource to the Environment. If you read the article you linked completely, you'll see it suggests registering an ApplicationContextInitializer in order to add new PropertySources so they'll be available in the way you're trying to use them.

Upvotes: 2

Related Questions