A Spring Property Handling Exercise

Version 0.0.2 of Spring-Data on GitHub focuses on properties handling. Populating a Hibernate MySQL connection is a pretty trivial task, right? Yes, but there are a number of angles to Spring property handling as you’ll see in this post.

Here’s a sample output of the new Property Handling demo of the Spring-Data app.

Configuration Class

We’ll be spending most of our time in our Spring Application Configuration class. This code segment of AppConfig.java gets us started.

@Configuration
@EnableConfigurationProperties
@EnableTransactionManagement
@ComponentScan(basePackages = "io.hibernate")
@PropertySource("classpath:application.properties")
@ImportResource("app-context.xml")
public class AppConfig {

private
@Value("${username}")
String username;

@Autowired
private Environment env;

@Autowired
private PropertyClass propertyClass;

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    final PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
...
}

 Annotations of Note

Here are a few interesting points on the Annotations pertaining to property handling.

@EnableConfigurationProperties – We need this to populate a class called PropertyClass so we can output propertyClass.getToken() shown in the output.

@PropertySource(…) – We need this to use the recommended env.getProperty(“someproperty”) approach. Without it we’ll be spitting out nulls.

@ImportResource(…) – We need this because we’re configuring a utility class to override the “username” environmental property I’ll mention later. The Utility class needs it so we add it here.

@Value vs Environment

In Spring-Data v0.0.2 are examples of using @Value assignment as well as the @Autowired Environment getProperty() approach. To make things interesting I’m using a “username” property name for my MySQL username. This is dumb, of course, because “username” conflicts with the System property of the same name. I haven’t read the following guidance anywhere, but it would seem obvious to always ALWAYS use property prefixes to avoid conflicts.

Our demonstration of System Property Overriding with Spring produced the following conclusions:

  1. env.getProperty(“username”) retrieved the system property every time, not my app property. I may have missed something, but I tried multiple configurations and always retrieved the System username, or “daveburke” instead of “devuser.”
  2. To retrieve an overridden value for “username” I added a utility class extending PropertyPlaceholderConfigurer using SYSTEM_PROPERTIES_MODE_OVERRIDE on setSystemPropertiesMode, with the class defined in an app-context.xml config file. (Thus the @ImportResource annotation above.) This enabled me to retrieve “devuser” for the username property rather than my username.
  3. @Value(“username”) retrieved the application.properties “username” value when setLocalOverride was set to true in the PropertySourcesPlaceholderConfigurer @Bean. That is shown below.
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
	PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();

	Resource[] resources = new ClassPathResource[]{
		new ClassPathResource("application.properties")};

	pspc.setLocations(resources);
	pspc.setIgnoreResourceNotFound(true);
	pspc.setIgnoreUnresolvablePlaceholders(true);
	pspc.setLocalOverride(true);
	return pspc;
}

Populating Class Properties and the Prefix

As part of the exercise we’re populating a class which I creatively called PropertyClass. It has a simple token property that we’ll display with propertyClass.getToken() from multiple locations in the application.

Here’s the simple PropertyClass class demonstrating @ConfigurationProperties(prefix…), so that “token” will be listed in application.properties with prefix “prop,” or prop.token.

@Component
@ConfigurationProperties(prefix="prop")
public class PropertyClass {

    private String token;
    public void setToken(String token) {
        this.token = token;
    }
    public String getToken() {
        return token;
    }

}

Streamlining for v0.0.3

Spring-Data is a demo and learning app, so now that we’ve pushed property handling to the extreme I’m going to clean the source a bit by adhering the use of prefixes. That allows me to get rid of the utility class for overriding system properties and no longer requires importing an XML configuration resource. I’ll standardize on using Environment to get properties, but will keep a @Value assignment for demo purposes. That means I’ll be keeping the PropertySourcesPlaceholderConfigurer to resolve ${…} @Value placeholders in my AppConfig class, but some times you need to use a @Value so it’s worth it.

Okay, Spring property handling is fun, but it’s now time to move on to using them!