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

  • How To Validate Names Using Java
  • How to Activate New User Accounts by Email
  • How to Develop Microservices With Spring Cloud and Netflix Discovery
  • Keep Your Application Secrets Secret

Trending

  • Start Coding With Google Cloud Workstations
  • Cookies Revisited: A Networking Solution for Third-Party Cookies
  • Issue and Present Verifiable Credentials With Spring Boot and Android
  • Automatic Code Transformation With OpenRewrite
  1. DZone
  2. Coding
  3. Frameworks
  4. DDD and Spring Boot Multi-Module Maven Project

DDD and Spring Boot Multi-Module Maven Project

In this post we will go through how to create Multi-Module Maven Project with Spring Boot following Domain-Driven Methodology.

By 
Purnima Jain user avatar
Purnima Jain
·
May. 21, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
45.4K Views

Join the DZone community and get the full member experience.

Join For Free

In this post we will go through how to create a Multi-Module Maven Project with Spring Boot following Domain-Driven Methodology.

Here I must confess that I am not being a total DDD purist here adhering to all the concepts but instead just covering the first mile. With this in your arsenal you should be in a position to extend this as per your project needs.

A multi-module project is built from a parent pom that manages a group of sub-modules. The parent pom is located in the project’s root directory and must have the packaging of type pom.

The sub-modules are regular maven projects that have packaging type different from pom, such as jar, war, ear. We have the option of running Maven build on separate module’s pom file or the parent’s pom file. By running the maven build on parent’s pom file all sub-modules will be built.

So, without further ado, let's get going.

Create a Parent Module

Open Eclipse, go to File --> New --> Other --> Maven --> Maven Project and click on Next.

select a wizard

Select "Create a simple project (skip archetype selection)" and click on Next.

new maven project

Input "com.purnima.jain" or something similar to Group Id.

Input "spring-boot-multi-module" or something similar to Artifact Id.

Change the packaging to pom. As this is the parent module, its packaging has to be pom.

Feel free to enter the Name and Description of your artifact.

Since it is a Spring Boot application that we are creating, we will include the following as Parent Project:

  • Group Id: org.springframework.boot
  • Artifact Id: spring-boot-starter-parent
  • Version: 2.2.6.RELEASE

And click on Finish.

new maven project

Create Child Modules

Next, we are going to create 5 sub-modules namely application, controller, domain, service, repository.

  • Child Module application is where your @SpringBootApplication, the Main class, will reside.
  • The controller houses the controller classes that provide REST end-points or similar stuff. This is also the module that houses all the DTOs that will be exposed to the outside world as JSON output from the REST end-points.
  • The domain is where your aggregate, entities, value-objects live along with Service and Repository Interfaces.
  • Service is where your Service implementations live.
  • The repository is where your Repository implementations live.

Let's start with creating the sub-module "application".

Right-click the parent project created above, "spring-boot-multi-module", New --> Other --> Maven Module and click on Next.

maven module

Select "Create a simple project (skip archetype selection)", input the Module name as "application", ensure that the selected "Parent Project" is the one created above and click on Finish.

name module

At this point, go to Windows in the top Toolbar in Eclipse and go to Show View --> Project Explorer. This view is better when working with multi-module projects.

Similarly, create other sub-modules like controller, domain, service, repository.

At this point, your Project Explorer view would look like this:

package explorer

Editing Pom.xml(s)

Edit your parent pom, spring-boot-multi-module/pom.xml, to look like below.

Add the properties section to set the Java version as 11. Properties are inherited from parent to child, so we need not mention Java version in any of our child poms.

Add the dependency spring-boot-starter-web in the dependencies section.

XML
 




x
37


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>org.springframework.boot</groupId>
8
        <artifactId>spring-boot-starter-parent</artifactId>
9
        <version>2.2.6.RELEASE</version>
10
    </parent>
11

          
12
    <groupId>com.purnima.jain</groupId>
13
    <artifactId>spring-boot-multi-module</artifactId>
14
    <version>0.0.1-SNAPSHOT</version>
15

          
16
    <packaging>pom</packaging>
17

          
18
    <properties>
19
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20
        <java.version>11</java.version>
21
    </properties>
22

          
23
    <dependencies>
24
        <dependency>
25
            <groupId>org.springframework.boot</groupId>
26
            <artifactId>spring-boot-starter-web</artifactId>
27
        </dependency>
28
    </dependencies>
29

          
30
    <modules>
31
        <module>application</module>
32
        <module>controller</module>
33
        <module>domain</module>
34
        <module>service</module>
35
        <module>repository</module>
36
    </modules>
37
</project>



Edit your child pom, application/pom.xml, to look like below.

In the dependencies section, add the dependency to controller, service, and repository modules. This is needed for auto-wiring and dependency injection.

XML
 




xxxxxxxxxx
1
31


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>com.purnima.jain</groupId>
8
        <artifactId>spring-boot-multi-module</artifactId>
9
        <version>0.0.1-SNAPSHOT</version>
10
    </parent>
11

          
12
    <artifactId>application</artifactId>
13

          
14
    <dependencies>
15
        <dependency>
16
            <groupId>com.purnima.jain</groupId>
17
            <artifactId>controller</artifactId>
18
            <version>${project.version}</version>
19
        </dependency>
20
        <dependency>
21
            <groupId>com.purnima.jain</groupId>
22
            <artifactId>service</artifactId>
23
            <version>${project.version}</version>
24
        </dependency>
25
        <dependency>
26
            <groupId>com.purnima.jain</groupId>
27
            <artifactId>repository</artifactId>
28
            <version>${project.version}</version>
29
        </dependency>
30
    </dependencies>
31
</project>



Edit your child pom controller/pom.xml to look like below.

In the dependencies section, add the dependency to the domain because the domain is where your Service Interfaces would reside which Controller will have to call.

XML
 




xxxxxxxxxx
1
21


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>com.purnima.jain</groupId>
8
        <artifactId>spring-boot-multi-module</artifactId>
9
        <version>0.0.1-SNAPSHOT</version>
10
    </parent>
11

          
12
    <artifactId>controller</artifactId>
13

          
14
    <dependencies>
15
        <dependency>
16
            <groupId>com.purnima.jain</groupId>
17
            <artifactId>domain</artifactId>
18
            <version>${project.version}</version>
19
        </dependency>
20
    </dependencies>
21
</project>



Leave your child pom domain/pom.xml as-it-is, no changes needed here.

XML
 




xxxxxxxxxx
1
14


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>com.purnima.jain</groupId>
8
        <artifactId>spring-boot-multi-module</artifactId>
9
        <version>0.0.1-SNAPSHOT</version>
10
    </parent>
11

          
12
    <artifactId>domain</artifactId>
13

          
14
</project>



Edit your child pom repository/pom.xml to look like below.

In the dependencies section, add the dependency to the domain because the domain is where your Repository Interfaces would reside which Repository implementations will have to implement.

XML
 




xxxxxxxxxx
1
21


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>com.purnima.jain</groupId>
8
        <artifactId>spring-boot-multi-module</artifactId>
9
        <version>0.0.1-SNAPSHOT</version>
10
    </parent>
11

          
12
    <artifactId>repository</artifactId>
13

          
14
    <dependencies>
15
        <dependency>
16
            <groupId>com.purnima.jain</groupId>
17
            <artifactId>domain</artifactId>
18
            <version>${project.version}</version>
19
        </dependency>
20
    </dependencies>
21
</project>



Edit your child pom service/pom.xml to look like below.

In the dependencies section, add the dependency to the domain because the domain is where your Service Interfaces would reside which Service implementations will have to implement.

XML
 




xxxxxxxxxx
1
21


 
1
<project xmlns="http://maven.apache.org/POM/4.0.0"
2
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4
    <modelVersion>4.0.0</modelVersion>
5

          
6
    <parent>
7
        <groupId>com.purnima.jain</groupId>
8
        <artifactId>spring-boot-multi-module</artifactId>
9
        <version>0.0.1-SNAPSHOT</version>
10
    </parent>
11

          
12
    <artifactId>service</artifactId>
13

          
14
    <dependencies>
15
        <dependency>
16
            <groupId>com.purnima.jain</groupId>
17
            <artifactId>domain</artifactId>
18
            <version>${project.version}</version>
19
        </dependency>
20
    </dependencies>
21
</project>



Our multi-module-maven Spring Boot project is created.

Seeing It in Action

To see it in action, we will have to add some classes in the various modules.

Go to the application module and create a package "com.purnima.jain.customer" in src/main/java and create the main @SpringBootApplication class here called CustomerApplication.java.

Java
 




xxxxxxxxxx
1
19


 
1
package com.purnima.jain.customer;
2

          
3
import org.slf4j.Logger;
4
import org.slf4j.LoggerFactory;
5
import org.springframework.boot.SpringApplication;
6
import org.springframework.boot.autoconfigure.SpringBootApplication;
7

          
8
@SpringBootApplication
9
public class CustomerApplication {
10

          
11
    private static final Logger logger = LoggerFactory.getLogger(CustomerApplication.class);
12

          
13
    public static void main(String[] args) {
14
        SpringApplication.run(CustomerApplication.class, args);
15
        logger.info("CustomerApplication Started........");
16
    }
17

          
18
}



Go to the controller module and create a package "com.purnima.jain.customer.controller" in src/main/java and create your controller here:

Java
 




xxxxxxxxxx
1
28


 
1
package com.purnima.jain.customer.controller;
2

          
3
import org.slf4j.Logger;
4
import org.slf4j.LoggerFactory;
5
import org.springframework.beans.factory.annotation.Autowired;
6
import org.springframework.web.bind.annotation.GetMapping;
7
import org.springframework.web.bind.annotation.PathVariable;
8
import org.springframework.web.bind.annotation.RestController;
9

          
10
import com.purnima.jain.customer.domain.aggregate.Customer;
11
import com.purnima.jain.customer.domain.service.CustomerService;
12

          
13
@RestController
14
public class CustomerController {
15

          
16
    private static final Logger logger = LoggerFactory.getLogger(CustomerController.class);
17

          
18
    @Autowired
19
    private CustomerService customerService;
20

          
21
    @GetMapping("customer/{customerId}")
22
    public Customer getCustomer(@PathVariable Integer customerId) {
23
        logger.info("Inside CustomerController........");
24
        return customerService.getCustomerById(customerId);
25
    }
26

          
27
}



Go to domain module and create a package "com.purnima.jain.customer.domain.aggregate" in src/main/java and create your Aggregate here:

Java
 




xxxxxxxxxx
1
23


 
1
package com.purnima.jain.customer.domain.aggregate;
2

          
3
public class Customer {
4

          
5
    private Integer customerId;
6
    private String customerName;
7

          
8
    public Customer(Integer customerId, String customerName) {
9
        super();
10
        this.customerId = customerId;
11
        this.customerName = customerName;
12
    }
13

          
14
    public Integer getCustomerId() {
15
        return customerId;
16
    }
17

          
18
    public String getCustomerName() {
19
        return customerName;
20
    }
21

          
22
}



In the same domain module, create another package "com.purnima.jain.customer.domain.service" in src/main/java and create your Service interface here:

Java
 




xxxxxxxxxx
1
10
9


 
1
package com.purnima.jain.customer.domain.service;
2

          
3
import com.purnima.jain.customer.domain.aggregate.Customer;
4

          
5
public interface CustomerService {
6

          
7
    public Customer getCustomerById(Integer customerId);
8

          
9
}



In the same domain module, create another package "com.purnima.jain.customer.domain.repository" in src/main/java and create your Repository interface here:

Java
 




xxxxxxxxxx
1
10
9


 
1
package com.purnima.jain.customer.domain.repository;
2

          
3
import com.purnima.jain.customer.domain.aggregate.Customer;
4

          
5
public interface CustomerRepository {
6

          
7
    public Customer getCustomerById(Integer customerId);
8

          
9
}



Go to the service module and create a package "com.purnima.jain.customer.service.implementation" in src/main/java and create your service implementation here:

Java
 




xxxxxxxxxx
1
28


 
1
package com.purnima.jain.customer.service.implementation;
2

          
3
import org.slf4j.Logger;
4
import org.slf4j.LoggerFactory;
5
import org.springframework.beans.factory.annotation.Autowired;
6
import org.springframework.stereotype.Service;
7

          
8
import com.purnima.jain.customer.domain.aggregate.Customer;
9
import com.purnima.jain.customer.domain.repository.CustomerRepository;
10
import com.purnima.jain.customer.domain.service.CustomerService;
11

          
12
@Service
13
public class CustomerServiceImpl implements CustomerService {
14

          
15
    private static final Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class);
16

          
17
    @Autowired
18
    private CustomerRepository customerRepository;
19

          
20
    @Override
21
    public Customer getCustomerById(Integer customerId) {
22
        logger.info("Inside CustomerServiceImpl........");
23
        Customer customer = customerRepository.getCustomerById(customerId);
24
        return customer;
25
    }
26

          
27
}



Go to the repository module and create a package "com.purnima.jain.customer.repository.implementation" in src/main/java and create your repository implementation here:

Java
 




xxxxxxxxxx
1
24


 
1
package com.purnima.jain.customer.repository.implementation;
2

          
3
import org.slf4j.Logger;
4
import org.slf4j.LoggerFactory;
5
import org.springframework.stereotype.Repository;
6

          
7
import com.purnima.jain.customer.domain.aggregate.Customer;
8
import com.purnima.jain.customer.domain.repository.CustomerRepository;
9

          
10
@Repository
11
public class CustomerRepositoryImpl implements CustomerRepository {
12
    
13
    private static final Logger logger = LoggerFactory.getLogger(CustomerRepositoryImpl.class);
14

          
15
    @Override
16
    public Customer getCustomerById(Integer customerId) {
17
        logger.info("Inside CustomerRepositoryImpl........");
18
        // Replace this code to retrieve from database
19
        Customer customer = new Customer(100, "A New Customer");
20
        return customer;
21
    }
22

          
23
}



Once all of this is done, run your Main class in the application module, CustomerApplication.java and you should see your code running.

To test it from a browser, go to http://localhost:8080/customer/100

You should see the JSON representation of Customers in the browser.

Source Code

You can download the source-code here.

Spring Framework Spring Boot Apache Maven Repository (version control) Dependency Java (programming language) application Interface (computing) Web Protocols

Opinions expressed by DZone contributors are their own.

Related

  • How To Validate Names Using Java
  • How to Activate New User Accounts by Email
  • How to Develop Microservices With Spring Cloud and Netflix Discovery
  • Keep Your Application Secrets Secret

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!