5 min read

Spring Boot 2: Directory structure and Convention

January 26, 2018

Spring Boot is an opinionated view of how a Spring based application should be implemented. Given that a lot of these opinions are on how Spring features should be used, Spring boot also emphasises on the structure of the spring boot project. In this post I will walk you through some important directories in a spring boot project.

Basic Structure

A typical project downloaded from Spring Initializer will look something like below.

+--- src/
|   +--- main/
|   |   +--- java/
|   |   |   +--- com/
|   |   |   |   +--- springhow/
|   |   |   |   |   +--- example/
|   |   |   |   |   |   +--- helloworld/
|   |   |   |   |   |   |   +--- HelloWorldApplication.java
|   |   +--- resources/
|   |   |   +--- application.properties
|   |   |   +--- static/
|   |   |   +--- templates/
|   +--- test/
|   |   +--- java/
|   |   |   +--- com/
|   |   |   |   +--- springhow/
|   |   |   |   |   +--- example/
|   |   |   |   |   |   +--- helloworld/
|   |   |   |   |   |   |   +--- HelloWorldApplicationTest.java
+--- pom.xml

On a higher level, spring follows and encourages basic maven directory structure. Let’s see in detail how these folders play out.

Java Source directories.

By default, the java classes should go under src/main/java. This is a maven default and this can be configured using project.build.sourceDirectory .

There are few conventions to follow in order to keep the project clean and maintainable.

Your base package should be in relevance to the groupId and artifactId of your project definition in pom.xml

For example, If the project is defined like this,

<groupId>com.springhow.example</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>

Then the convention is to keep com.springhow.example.helloworld as your base package of the application.

Test sources

Test sources are not different from application source files. These Test classes ( Usually Junit) are created under src/test/java. Their supporting test files would go into src/test/resources.

Configuration files

The configuration files go under src/main/resources. We have src/test/resources if you need different configuration files in test phase.

By default, SpringApplication will check and load properties from application.properties in the following order.

  1. The classpath root
  2. /config location within classpath
  3. the current directory from where the application was started
  4. A /config subdirectory of the current directory from where the application was started

If the application.properties file is available in multiple places at once, Spring applies precedence exactly in the above order.

spring-boot-maven-plugin moves all the files under src/main/resources to classpath root. So the basic strategy is to keep the file exactly at src/main/resources/application.properties

YAML Support

You can also use application.yml file as an alternative for application.properties.

If the application.properties look like this,

app.path=/path
app.database.username=user
app.database.password=pass

the equivalent application.yml will look something like this.

app:
  path: '/path'
  database:
    username: 'user'
    password: 'pass'

Basically its just another way of representing configuration properties. But in a readable way.

Profile specific properties

Environment properties can be activated with per profile basis by creating properties files with pattern application-{profile}.properties.

This way you can have application-dev.properties activated when the application is started wth dev profile.

Static web content

In a spring boot web application, static files like HTML, CSS, JS and IMAGE files can be served directly from any of the following classpath localtions out of the box. No configuration required.

  • /META-INF/resources/
  • /resources/
  • /static/
  • /public/

Note that these are classpath locations not the actual folders. The ideal way of placing your content in these class path is to place them under src/main/resources. Any files kept here are automatically added to the classpath with the exact folder structure.

In simple terms, The file test.html in any of the following paths in project can be accessed using http://localhost:8080/test.html in the exact order.

  1. src/main/java/META-INF/resources/test.html
  2. src/main/java/resources/test.html
  3. src/main/java/resources/resources/test.html
  4. src/main/java/resources/static/test.html
  5. src/main/java/resources/public/test.html

Dynamic web content (Templates)

Spring supports the following template engines by default. These templates can be activated using appropriate spring boot starters.

  • FreeMarker - spring-boot-starter-freemarker
  • Groovy - spring-boot-starter-groovy
  • Thymeleaf - spring-boot-starter-thymeleaf
  • Mustache - spring-boot-starter-mustache

All these template engines will resolve their template files from the path src/main/resources/template .

For Thymeleaf engine, a straight forward code sample would be,

@RequestMapping("/hello")
public String greeting(
@RequestParam(value = "user") String useName,Model model){
        model.addAttribute("user",useName);
        return "hello";
        }

This wil use the template file src/main/resources/template/hello.html to render the request http://localhost:8080/hello?user=World.

pom.xml

In a spring boot project, most of the modules can be enabled or disabled just by adding a set of starters. For a maintainable code,

  • Only add needed starters. This keeps the application lighter. Unwanted starter may lead to extra autowired beans.
  • Most of the starters ship with their own transitive dependencies. So you may never need to specify versions. Most of the IDE’s already highlight this unwanted version tags.
  • Know your starter dependencies. This way, You may never need to write configurations.