Understanding Spring's Environment Abstraction

When working with Spring Boot, some auto-configuration can happen seemingly by magic. For example, in a traditional Spring application with Java-based configuration, you might configure an H2 database using the following block of code to set the type of the database and run some scripts to initialize it:

1
2
3
4
5
6
7
8
@Bean
public DataSource dataSource() {
    return new EmbeddedDataSourceBuilder()
        .setType(H2)
        .addScript("taco_schema.sql")
        .addScripts("user_data.sql", "ingredient_data.sql")
        .build();
}

With Spring Boot, you can remove this entire block of code and use auto-configuration. If the H2 dependency is available in the classpath, Spring Boot will automatically create the DataSource and add it as a Bean to Spring’s application context and apply SQL scripts as long as they are named schema.sql or data.sql. Spring Boot does this auth-configuration by leveraging the Spring environment that collects the set of properties available to a Java application and uses those properties to configure beans in Spring’s application context. The following figure from Spring in Action shows how the Spring environment is generated by some of the available configuration property sources available in a typical Java application.

assets/the-spring-environment.png

Spring configuration generated from Java property sources.

The beans that are automatically configured by Spring Boot are all configurable by properties drawn from the Spring environment or from defaults specified by Spring Boot. As a simple example, you can change the the configured port for serving an application to 9090 by adding configuration to application.yml:

1
2
server:
    port: 9090

or by specifying the port as a command-line argument:

1
$ java -jar my-app.jar --server.port=9090

Returning to our DataSource example, we can change the configuration of the data source for our application to use a MySQL database instead of H2 by specifiying it in our application.yml:

1
2
3
4
5
spring:
    datasource:
    url: jdbc:mysql://sookocheff.com/appdb
    username: admin
    password: adminpass

Spring Boot will use this connection data when autoconfiguring the DataSource bean, using a default JDBC connection pool provided by Tomcat if Tomcat is on the classpath. Of course, you could provide further configuration to specifiy the connection pool implementation by including an implementation that Spring Boot can autoconfigure on the classpath, or by explicitly configuring your connection pool using Spring environment property sources.

In all cases, Spring will read from properties available in the Spring environment and configure any Bean’s in the Spring application context as required. Although this post touches on a few of the property sources in a typical Spring application, it is not exhaustive. A full list of the methods for setting properties is available here, allowing you to use configure your application in any number of ways, and having Spring and Spring Boot respect that configuration and use sane defaults for the rest.

spring  java 

See also

comments powered by Disqus