Build Your Custom Spring Initializer

Amit Kumar
6 min readJul 18, 2022

--

Photo by Michael Dziedzic on Unsplash

If you ask any Java/Spring boot developers how do they start the initial project setup. Almost all of them will tell you that they use start.spring.io to create the initial setup. If you are reading this blog probably you also have used start.spring.io to create project.

Someone has said about start.spring.io that “this is best place on internet”.

For those who don’t know, I am guessing that they are smart enough to catch what start.spring.io is from the above introductory comments.

Agenda

  • Motivation
  • How to build custom spring initializer server
  • How to integrate custom spring initializer server in intellij
  • Conclusion

So if Spring initializer is such an amazing place, why do you need to create your own spring initializer server? Following points may satisfy this curiosity.

  • For a large team to work on microservices architecture, they need to create spring boot projects/libraries constantly. Having a custom spring initializer allows your developers to generate projects/libraries where they don’t have to worry about the package name, project name conventions etc.
  • List of dependencies can be configured as per your needs overriding default dependencies list or with them as well.
  • Version of project, Type of build tool, Java version, Project descriptions etc all can be defined, so no hassle of remembering these stuff.

Simply put, by using custom spring initializer you can make your teammates to follow your own project generation guidelines, allowing them to focus on actual development.

How can one create a custom spring initializer server? Well, that’s pretty simple,let us see in this section.

First of all go to start.spring.io and create a project custom-spring-initializer-service with web dependency.

How ironic is that to replace start.spring.io, we need it as well.

Replace the dependencies section of your project in the build.gradle file by following the script.

dependencies {
implementation ‘org.springframework.boot:spring-boot-starter-web’
implementation(‘io.spring.initializr:initializr-web’)
implementation(“io.spring.initializr:initializr-generator-spring”)
}
dependencyManagement {
imports {
mavenBom “io.spring.initializr:initializr-bom:0.12.0”
}
}

Your build.gradle should look like the following.

plugins {
id ‘org.springframework.boot’ version ‘2.6.9’
id ‘io.spring.dependency-management’ version ‘1.0.11.RELEASE’
id ‘java’
}
group = ‘com.myorg’
version = ‘0.0.1-SNAPSHOT’
sourceCompatibility = ‘11’
repositories {
mavenCentral()
}
dependencies {
implementation ‘org.springframework.boot:spring-boot-starter-web’
implementation(‘io.spring.initializr:initializr-web’)
implementation(“io.spring.initializr:initializr-generator-spring”)
}
dependencyManagement {
imports {
mavenBom “io.spring.initializr:initializr-bom:0.12.0”
}
}
tasks.named(‘test’) {
useJUnitPlatform()
}

Try building the project.

If it fails, delete the test cases and build again. This time it should be built successfully.

Your custom spring initializer server is ready but it is the same as the default spring initializer. Why? Because we haven’t overridden the default configuration in the service.

Try hitting the server URL(localhost:8080) in the browser, you will get a json like this.

{“_links”:{“dependencies”:{“href”:”http://localhost:9090/dependencies{?bootVersion}","templated":true}},"dependencies":{"type":"hierarchical-multi-select","values":[]},"type":{"type":"action","values":[]},"packaging":{"type":"single-select","values":[]},"javaVersion":{"type":"single-select","values":[]},"language":{"type":"single-select","values":[]},"bootVersion":{"type":"single-select","values":[]},"groupId":{"type":"text","default":"com.example"},"artifactId":{"type":"text","default":"demo"},"version":{"type":"text","default":"0.0.1-SNAPSHOT"},"name":{"type":"text","default":"demo"},"description":{"type":"text","default":"Demo project for Spring Boot”},”packageName”:{“type”:”text”,”default”:”com.example.demo”}}

If you look carefully, It is returning the same project configuration as the default spring initializer.

So let’s override the configuration one by one.

Note:- All below props will under initializr as shown in 1st example.

  1. groupId, artifactId, packageName, project name and project description
initializr:
groupId:
value: com.myorg
artifactId:
value: my-service
packageName:
value: com.myorg.demo
name:
value: my-service
description:
value: A sample myorg project

Add above props in application.yml file. These props as name suggest will override default groupId, artifactId, packageName,project description and project name.

Again hit the URL(localhost:8080) and verify if above props values are overridden.

2. Now let us set our java versions, let say we want to only see java version 11 as our project support us. In default spring initializer, right now option for 8,11,17 and 18 came. To override these simply add below props under initializer in application.yml file.

javaVersions:
- id: 11
default: true

Try hitting again, and if response changes for java versions .

3. In the same way, we can override the languages option, packaging options and types options(Maven/Gradle) as shown below.

Again try hitting localhost:8080 and verify response.

Try to play with it by adding more languages, versions etc and verify responses.

4. Now main aspect how to override default dependencies or add your own dependencies besides the default one. Below props shows how to add your own dependencies.

While providing the custom dependencies, it is necessary to provide groupId, artifactId, version, and an unique identifier id as we can see in above props.

Now if you hit localhost:8080, you will only see these two dependencies in the list.

5. How to add default dependencies as well in the list? So spring identify its starter dependencies by its unique ID e.g. for starter-web unique id is web, for starter-jpa it is jpa and so on. To include these in your custom spring initializer server you need to do following.

initializr:
dependencies:
- name: Web
content:
- name: Web
id: web
description: Full-stack web development with Tomcat and Spring MVC

Again try hitting localhost:8080 and verify response.

So, end of this section where we have seen how to override the default spring initializer configurations. Response now looks like this.

{“_links”:{“maven-project”:{“href”:”http://localhost:9090/starter.zip?type=maven-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}","templated":true},"gradle-project":{"href":"http://localhost:9090/starter.zip?type=gradle-project{&dependencies,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}","templated":true},"dependencies":{"href":"http://localhost:9090/dependencies{?bootVersion}","templated":true}},"dependencies":{"type":"hierarchical-multi-select","values":[{"name":"MyOrg","values":[{"id":"my-dependecies1-id","name":"my-dependecies1","description":"Dependency description”},{“id”:”my-dependecies2-id”,”name”:”my-dependecies2",”description”:”Dependency description”}]},{“name”:”Web”,”values”:[{“id”:”web”,”name”:”Web”,”description”:”Full-stack web development with Tomcat and Spring MVC”}]}]},”type”:{“type”:”action”,”default”:”gradle-project”,”values”:[{“id”:”maven-project”,”name”:”Maven Project”,”description”:”Generate a Maven based project archive”,”action”:”/starter.zip”,”tags”:{“build”:”maven”,”format”:”project”}},{“id”:”gradle-project”,”name”:”Gradle Project”,”description”:”Generate a Gradle based project archive”,”action”:”/starter.zip”,”tags”:{“build”:”gradle”,”format”:”project”}}]},”packaging”:{“type”:”single-select”,”default”:”jar”,”values”:[{“id”:”jar”,”name”:”Jar”},{“id”:”war”,”name”:”War”}]},”javaVersion”:{“type”:”single-select”,”default”:”11",”values”:[{“id”:”11",”name”:”11"}]},”language”:{“type”:”single-select”,”default”:”java”,”values”:[{“id”:”java”,”name”:”Java”}]},”bootVersion”:{“type”:”single-select”,”values”:[]},”groupId”:{“type”:”text”,”default”:”com.myorg”},”artifactId”:{“type”:”text”,”default”:”my-service”},”version”:{“type”:”text”,”default”:”0.0.1-SNAPSHOT”},”name”:{“type”:”text”,”default”:”my-service”},”description”:{“type”:”text”,”default”:”A sample myorg project”},”packageName”:{“type”:”text”,”default”:”com.myorg.demo”}}

Let us now see how to use this in Intellij to create spring boot projects.

Have you heard about Spring Initializr and Assistance, if not, install this plugin in Intellij.

After installing this, restart your IDE and try to create a new project, you will see in the left panel an option of Spring initializer, select it and a next panel you will have two options

  1. Default start.spring.io
  2. Custom (Configure your own server by adding http://locahost:8080)

Congrats, you are ready to go with your custom spring initializer server.

Click Next. You will see all the project configuration you have made in application.yml file.

Now, if you click next twice, it will give a pop up to select atleast one dependency.

But why is this happening? Because we haven’t provided spring boot versions in configurations.

Add below code in Spring boot Main class and run again. This time you will see dependencies list with available spring boot versions.

@Bean
SaganInitializrMetadataUpdateStrategy saganInitializrMetadataUpdateStrategy(
RestTemplateBuilder restTemplateBuilder, ObjectMapper objectMapper){
return new SaganInitializrMetadataUpdateStrategy
(restTemplateBuilder.build(), objectMapper);
}

Hurray!!!! You have done it. Select dependencies and click next you will next window to choose project location and finish. After Finishing your initial project setup is ready.

Congrats if you have come here while learning and doing.

Bonus:

  • You can create your own UI as well just like start.spring.io. Try exploring.

Resources:

Github:

Thanks for reading.

Clap and follow to read more such articles.

--

--

Amit Kumar

Spring, Spring boot, Java developer, code quality, learning , writing and sharing.