Create a Spring Boot Application Using Multiple Maven Modules

Spring Boot has been receiving a lot of hype lately. There are plenty of materials online. However, most of the examples used to demonstrate Spring Boot are rather simple. In 99% of cases, a single Maven module is used. But, in the real world, developers are building complex applications and they want to structure their code across multiple modules.

Let’s consider a typical use case. We have a web application that manages hotel bookings. We could split the concerns of the projects in 3 parts:
– a module for the domain logic (entities, services, logic). Package name is rc.domain.*
– a module for the infrastructure (database access, etc). Package name is rc.persistence.*
– a module for the web app (controllers, main Spring Boot App. class). Package name is rc.web.*

Each module is an independent Maven project and has it’s own pom.xml file. The main application class resides in the “web” maven module and looks like this.

// !!! Will not work by default. Spring only scans for components in the module and packages where the main // class resides. In our case, this is rc.web.*
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

However, if we run this application, it will not work. You will get some nasty exceptions. Some of your components/services/entities/repositories could not be found and no bean was created for them. The reason behind this behaviour is that Spring only scans for components in the module where the main application class resides. So, if you have your entities in a different module, they will not be available for auto wiring. If you have your repositories in a different module, they will also not be available for auto wiring. You get the idea. We need to tell Spring to scan for our beans in other modules as well. And this can be done very easily be adding the following annotations to our Spring Boot main application class.

// Will work. Now Spring will scan for components in all packages that
// start with rc, even if they reside in different Maven modules. So rc.core, rc.persistence and rc.web are scanned
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"rc"})
@EntityScan(basePackages = {"rc"})
@ComponentScan(basePackages = {"rc"})
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

There is one more thing that you need to keep in mind. If you want to build your project with Maven, you need to make sure that the “spring-starter-web” dependency and the “maven-build-plugin” are written in the pom.xml file of the module which contains the main Spring Boot application class. In my example, they should be written in the pom.xml file of the “web” module. If your application is working when you run it from the IDE, but fails with exceptions when you try to run it using Maven, then this is most likely the cause.

You can find a working example on GitHub.

You can also check out the YouTube tutorial that I created for this topic: