What code structure use for Spring Boot applications?

January 04, 2020 No comments Code Structure Spring Boot Spring

1. Introduction

In this article, we will focus on Spring Boot application code structure and we will try to bring the best practices in that subject.

2. Code structure in Spring Boot applications

Firstly, Spring Boot does not require any specific code structure to work. However, there are some good practices that every Spring Boot developer should follow. In general, the best way to organize web applications code is to use structure by feature approach.

But let's compare two approaches first:

  • code organized by layer
  • code organized by feature.

2.1. Package by layer

In package by layer architecture, classes are organized in application layers, for example DAO (Data Access Objects) will be located in dao or repository package, services in service package, model classes in model package and so on.

Example project structure in package by layer approach can look like the following:

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- controller
         |  +- ProductController.java
         |  +- OrderContrller.java
         |  +- CustomerController.java
         |   
         +- dao
         |   +- ProductRepository.java
         |   +- OrderRepository.java
         |   +- CustomerRepository.java
         |   
         +- model
         |   +- Product.java
         |   +- Order.java
         |   +- Customer.java
         |
         +- service
            +- ProductService.java
            +- OrderService.java
            +- CustomerService.java

At first look, such class placement seems to be readable. However, when software projects grow it gets more and more difficult to find the class we have to change for a new requirement. This approach has many other disadvantages:

  • hard to ship a feature or a module in isolation,
  • many merge conflicts with other co-workers, who worked on the different feature but in the same code structure,
  • looking just at the top-level package gives zero information about the application features,
  • in order to work on an existing feature, we need to scan all layers to find connected by feature classes,
  • virtually every package depends on virtually all packages, making code refactors painful.

2.2. Package by feature

In package by feature approach, all classes related with one feature are located in the same package. When application grow, only the number of namespaces increases due to new features being implemented.

Example structure by feature can look like the following:

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- product
         |   +- Product.java
         |   +- ProductController.java
         |   +- ProductService.java
         |   +- ProductRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java

The feature approach gives many advantages:

  • don't have to scroll up and down to find classes related with a single feature,
  • features can be deleted by a single right click on a single package,
  • testing is easy,
  • refactoring is easy,
  • features can be shipped separately.

3. Main application class location

Spring Boot recommends placing the main application class in a root package above other classes. The main reason to do so is that placing @SpringBootApplication or @ComponentScan on that application class defines a base "search package". Spring Boot will seek for other components in packages that are in parent-child relationship to this root package.

The example of wrong order package placement in Spring Boot application:

com
 +- example
     +- myapplication
     |   +- Application.java
     |   |
     |   +- product
     |       +- ProductController.java
     |   
     +- order // wrong package placement, Application root package is com.example.myapplication
         +- OrderController.java // this component will not be initialized by spring
{{ message }}

{{ 'Comments are closed.' | trans }}