DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • DGS GraphQL and Spring Boot
  • A Practical Guide to Creating a Spring Modulith Project
  • Setting Up Local Kafka Container for Spring Boot Application
  • Spring Boot Application With Spring REST and Spring Data MongoDB

Trending

  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • Unlocking the Benefits of a Private API in AWS API Gateway
  • AI Meets Vector Databases: Redefining Data Retrieval in the Age of Intelligence
  • Unlocking AI Coding Assistants Part 4: Generate Spring Boot Application
  1. DZone
  2. Coding
  3. Frameworks
  4. Best Practices for Multi-Module Projects With Spring Boot

Best Practices for Multi-Module Projects With Spring Boot

Build and work with multi-module projects in Spring Boot: five practical tips on how to structure your modules properly.

By 
Thomas Surmann user avatar
Thomas Surmann
·
Nov. 21, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
2.6K Views

Join the DZone community and get the full member experience.

Join For Free

Most applications in the real world will accumulate a large amount of features and code in the long run. Multi-module projects are a good approach to structuring the application without having to go down the complex path of microservices. The following five tips can help to better organize such Spring Boot projects in the long run.

#1 Find a Proper Module Structure

In general, the use of two modules, "base" and "web," is a good starting point for Spring Boot applications. The "base" module describes the basic setup, for example, database settings, and provides utility classes. Standards defined here then apply to all further modules. In "web," all modules are combined, and the executable application is built — our executable "fat jar."

The structure of the intermediate modules should be less technical and more domain-driven. First, here is a negative example of partitioning an online store.

Poor example of technical structuring

Poor example of technical structuring

While a purely technical separation is possible, it offers little advantage: for a developer to perform a typical task ("add a filter to the search"), all the artifacts involved must be gathered from multiple modules. With a domain-driven subdivision, however, customization would be limited to one module for many tasks. 

Good example of domain-driven modularization

Good example of domain-driven modularization

When the application is extended over time, it is easy to add more modules with a domain-driven structure, e.g., "blog." With a technical separation, this makes little sense, and at some point, you will end up with a big ball of mud.

#2 Minimize Dependencies

Each module should contain all artifacts that it needs to provide its own functionality in order to minimize dependencies on other modules. This includes classes, templates, dependencies, resources, and so on.

An interesting question is whether the ORM layer should be stored in a central module or split among the respective modules. Nowadays, the support for separation is very good, so that actually nothing speaks against it. Each module can contain its own JPA entities and Flyway / Liquibase changelogs. When running an integration test within a module, a partial database schema would be created based on the current and all referenced modules.

A useful library that supports separating the modules is Springify Multiconfig. It allows each module to contain its own application-mc-xx.yml file to store specific configuration of that module. Without this library, the entire config must be in the application.yml of the "base" module.

#3 Continuous Improvement

A bad architecture is better than none, but the best structure of the modules is never clear from the beginning. Since all dependencies are within one application, the partitioning can be adjusted with a single pull request if necessary. With microservices, an extensive, multi-stage procedure would usually be required.

It is always worthwhile to question the current status and further improve it in the long term.

#4 Gradle API vs. Implementation

While developing the code of a module, the directly and indirectly referenced modules of the current project are always available. When external libraries are declared as a dependency, there are two possibilities in Gradle: with api (formerly compile) the library is also visible indirectly, whereas with implementation a library is only available within the current module. In other words, if a module is referenced and a library there is included with implementation, it will be hidden and cannot be used in the code.

In the final app, all dependencies end up in the single "fat jar" again, but during the build process, invalid accesses would already be prevented. Following this approach, the libraries available during development should remain cleaner.

#5 Use Separate Test Jars

Each module has its own tests to validate the functionality it contains. Sometimes, however, test data is created, or utility methods are provided that are needed in the modules that build on top of them — for example, to create test users.

In general, classes and data that are only needed for tests should not be contained in the application that is later running in production. For Maven, Gradle, and Kotlin Script, there is a way to create separate test jars for each module. These can then be referenced specifically for the test code. More backgrounds on the implementation are here for Maven and here for Gradle.

Conclusion

Multi-module projects are getting increased attention right now, as microservices come with many challenges in practice, and the extra effort is only really worth it for larger development teams. By following best practices, well-structured applications can be developed for the real world. If later on you want to switch to microservices, individual modules can be broken out as standalone apps.

application Spring Boot

Published at DZone with permission of Thomas Surmann. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • DGS GraphQL and Spring Boot
  • A Practical Guide to Creating a Spring Modulith Project
  • Setting Up Local Kafka Container for Spring Boot Application
  • Spring Boot Application With Spring REST and Spring Data MongoDB

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!