springboot_multi_module
springboot_multi_module copied to clipboard
Gradle + Spring Boot + Multi Module
trafficstars
Spring Boot Multi Module using Gradle
Requirements
- Gradle
- IntelliJ
Setup
- IntelliJ --> Create New Project --> Gradle + Java
- GroupId: com; ArtifactId: springboot-multi-module
- Check "use auto-imports"
- Finish
Porject Structure
- Basic project structure,

- If the root has any src/ folder then delete it. No problem.
Create Modules
- We will create two modules:
- common (is a library which can be used by all application modules)
- search (Application module which accepts requests. Search will include common module.)
Module Creation
- Right click on root project --> New --> Module
- Select Gradle + Java
- Give ArtifactId as "common".
- Do next ... Finish
- Now you can see in
root/settings.gradlewe have include 'common'. - Similarly we will create search module.
- Final root/settings.gradle will be as follows,
rootProject.name = 'springboot-multi-module'
include 'common'
include 'search'
Setup common module
- Our common module is just a library. This module will be shared among all the modules. We don't include any web related dependencies here. We just need to say that this is a spring boot application.
common/build.gradle
buildscript {
repositories { mavenCentral() }
}
plugins { id "io.spring.dependency-management" version "1.0.4.RELEASE" }
ext { springBootVersion = '2.0.0.RELEASE' }
apply plugin: 'java'
apply plugin: 'idea'
jar {
baseName = 'springboot-multi-module-library'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") }
}
- Let's create source directory. Right click on common module --> New --> Directory --> src/main/java
- Right click on common/src/main/java --> New --> Package --> com.common
- Create class
Product(id, name, price) undercom.common. - That's it. common module is ready to use.
- Do,
./gradlew buildto check the build status.
Setup search application module
- Search module is an application which serves API request and returns response. Hence we need to include web dependency for this module. Web dependency will have tomcat as a transitive dependency. No need to explicitly include tomcat.
- Also search module requires common module. Include it under dependecy as
compile project(':common') search/build.gradle
buildscript {
ext { springBootVersion = '2.0.0.RELEASE' }
repositories { mavenCentral() }
dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
jar {
baseName = 'springboot-multi-module-search'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-web')
compile project(':common')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
- Create src/main/java/ directory under search. Create package com.search.
- Create class
SearchApplicationwith following code,
package com.search;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.common.Product;
@RestController
@SpringBootApplication(scanBasePackages = "com")
@RequestMapping("/search")
public class SearchApplication {
@RequestMapping("/hello")
@GetMapping
public String hello() {
return "Search: Hello";
}
public static void main(String[] args) {
SpringApplication.run(SearchApplication.class, args);
}
}
NOTE: In the above code main method is important. This is where Spring Boot will start this module. scanBasePackages is another important annotation, as it says to scan all the components under the package com. So ideally all our modules packages are under com structure. If you have the code in a different package then include it as scanBasePackages = {"com", "another"}
- We will explicitly mention Tomcat server port(as 8100) else it will by default run in
8080. - Create
resourcesdirectory src/main/ and addapplication.propertiesfile. Giveserver.port=8100as property.
Run (let's see whether we are able to access search API or not)
- Under root (springboot-multi-module) --> run,
./gradlew buildto build and then run./gradlew :search:bootRunto run search application.- First
./gradlew buildwill make common library to be compiled and ready to use. - Second,
./gradlew :search:bootRunwill make search application to run on port 8100
- First
- Open Postman/Chrome, http://localhost:8100/search/hello
Create custom class(Product) and use it
- Create another api under search. For now lets call it, "/product"
- Make sure we say this api produces a JSON.
@RequestMapping(value = "/product",
method = RequestMethod.GET,
produces = {"application/json"})
public Product product() {
return new Product(1, "Laptop", 45000d);
}
- Build and Run,
./gradlew build && ./gradlew :search:bootRun - http://localhost:8100/search/product
{
id: 1,
name: "Laptop",
price: 45000
}
Get particular Product by passing its id using @PathVariable
- NOTE: @PathVariable is to get the value from URL. @RequestBody is used when we pass input as JSON/XML etc. (You will see this usage later)
- Created
com.common.ProductServicefor products creation.- To search by id of the product where id is passed as a url param.
- To return a list of products as JSON.
- Add few more apis in search,
@RequestMapping(value = "/product/{id}",
method = RequestMethod.GET,
produces = {"application/json"})
public Product productWith(@PathVariable("id") long id) {
Optional<Product> product = ProductService.getProducts().stream().filter(p -> p.getId() == id).findFirst();
return product.get();
}
@RequestMapping(value = "/products",
method = RequestMethod.GET,
produces = {"application/json"})
public List<Product> products() {
return ProductService.getProducts();
}
Run
- Build & Run in together, ./gradlew build && ./gradlew :search:bootRun
- http://localhost:8100/search/product/1 or http://localhost:8100/search/products
Lets create a POST call to insert a Product
- We can pass a Product as a JSON to api, consume it as JSON and convert it to Product using
@RequestBodyannotation. - In
ProductServiceadd a method tocreateProductand add it to existing products list. - POST method as follows,
@RequestMapping(value = "/product/create",
method = RequestMethod.POST,
consumes = {"application/json"}
)
public String createProduct(@RequestBody Product product) {
if (ProductService.createProduct(product)) {
return "Created Product = " + product.toString();
}
return "Creation failed for Product = " + product.toString();
}
- Open Postman,
- Select POST
- http://localhost:8100/search/product/create
- Body --> raw and select type as JSON.
- Enter the below input in the body placeholder,
{
"name": "Product-10",
"price": 10
}
- Run it and access the above url with JSON as params.
Conclusion
- We have successfully created a Gradle Multi Module Spring Boot application using IntelliJ.