7. Creating your own instance

Spring Initializr is split across three main modules:

Because it contains several auto-configurations, creating your own instance is quite easy, actually you could get started using Spring Initializr itself to generate a starting point!

Create a new project with the web dependency and add the following dependency:

<dependency>
    <groupId>io.spring.initializr</groupId>
    <artifactId>initializr-web</artifactId>
    <version>0.4.0.RELEASE</version>
</dependency>

Or if you are using Gradle:

compile("io.spring.initializr:initializr-web:0.4.0.RELEASE")

If you start the application, you’ll see the familiar interface but none of the drop down lists have values (except the one for the Spring Boot version, we will come back to that later). In the rest of this section, we will configure those basic settings.

[Tip]Tip

Most of the settings are configured via application.properties using the initializr namespace. Because the configuration is highly hierarchical, we recommend using the yaml format that is more readable for such structure. If you agree, go ahead and rename application.properties to application.yml.

7.1 Configuring basic settings

Most of the drop-down lists are configured via a simple list-based structure where each entry has an id, a name and whether that entry is the default or not. If no name is provided, the id is used instead.

Let’s configure the languages and the Java versions we want to support:

initializr:
  javaVersions:
    - id: 9
      default: false
    - id: 1.8
      default: true
  languages:
    - name: Java
      id: java
      default: true
    - name: Kotlin
      id: kotlin
      default: false

If you click on the "Switch to the full version" link, the two drop down lists now offer the options and default values defined above.

Spring Initializr supports java, groovy and kotlin and additional languages can be added in your own customization.

The available packagings are also configurable that way:

initializr:
  packagings:
    - name: Jar
      id: jar
      default: true
    - name: War
      id: war
      default: false

These two packaging types are the only one explicitly supported at the moment.

7.2 Configuring available Spring Boot versions

If you look at the project home page for Spring Boot, the latest versions are displayed. And you’ve probably noticed that they match the drop down list that you automatically get with a default instance of the Initializr. The reason for that is that Spring Initializr calls an API on spring.io to retrieve the latest versions automatically. This makes sure that you always get the latest available versions.

If you are behind a proxy, or need to customize the RestTemplate that is used behind the scenes, you can define a RestTemplateCustomizer bean in your configuration. For more details, check the documentation.

If you don’t want the version to be upgraded automatically, you need to override the InitializrMetadataProvider bean to provide your own metadata for the service. For instance, you could swap to an implementation that always returns the contents of static application.yml:

@Bean
public InitializrMetadataProvider initializrMetadataProvider(
        InitializrProperties properties) {
    InitializrMetadata metadata = InitializrMetadataBuilder
            .fromInitializrProperties(properties).build();
    return new SimpleInitializrMetadataProvider(metadata);
}

The thing to remember is that, by default, you don’t have to worry about upgrading your instance when a new Spring Boot version is released. However, you may need to configure caching to avoid requesting that service too often.

7.3 Configuring available project types

The available project types mostly define the structure of the generated project and its build system. Once a project type is selected, the related action is invoked to generate the project.

By default, Spring Initializr exposes the following resources (all accessed via HTTP GET):

  • /pom.xml generate a Maven pom.xml
  • /build.gradle generate a Gradle build
  • /starter.zip generate a complete project structure archived in a zip
  • /starter.tgz generate a complete project structure archived in a tgz

Each type also defines one or more tags that provides additional metadata entries to qualify the entry. The following standard tags exist:

  • build: the name of the build system to use (e.g. maven, gradle)
  • format: the format of the project (e.g. project for a full project, build for just a build file).

By default, the HTML UI filters all the available types to only display the ones that have a format tag with value project.

You can of course implement additional endpoints that generate whatever project structure you need but, for now, we’ll simply configure our instance to generate a Gradle or a Maven project:

initializr:
  types:
    - name: Maven Project
      id: maven-project
      description: Generate a Maven based project archive
      tags:
        build: maven
        format: project
      default: true
      action: /starter.zip
    - name: Gradle Project
      id: gradle-project
      description: Generate a Gradle based project archive
      tags:
        build: gradle
        format: project
      default: false
      action: /starter.zip
[Note]Note

If you intend to build a custom client against your service, you can add as many tags as you want, and process them in the client in a way that makes sense for your users.

For instance, the spring boot CLI uses them as a shortcut to the full type id. So rather than having to create a Gradle project as follows:

$ spring init --type=gradle-project my-project.zip

You can simply define a more convenient build parameter:

$ spring init --build=gradle my-project.zip

With that configuration, you should be able to generate your first project, congratulations! Let’s now add dependencies so that you can start searching for them.

7.4 Configuring dependencies

The most basic dependency is composed of:

  • An id used in clients to refer to it
  • The full maven coordinates of the dependency (groupId and artifactId)
  • A display name (used in the UI and the search results)
  • A description can (and should) be added to provide more information about the dependency

Spring Initializr automatically considers that a dependency without maven coordinates defines an official Spring Boot starter. In such a case, the id is used to infer the artifactId.

For instance, the following configures the spring-boot-starter-web Starter:

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

Each dependency is contained in a group that gathers dependencies sharing a common surface area or any other form of grouping. In the example above, a Web group holds our unique dependency. A group can also provide default values for various settings, see the dedicated how-to for more details.

In our spring-boot-starter-web example above, the dependency is managed by Spring Boot so there is no need to provide a version attribute for it. You’ll surely need to define additional dependencies that are not provided by Spring Boot and we strongly recommend you to use a Bill Of Materials (or BOM).

If no BOM is available you can specify a version directly:

initializr:
  dependencies:
    - name: Tech
      content:
        - name: Acme
          id: acme
          groupId: com.example.acme
          artifactId: acme
          version: 1.2.0.RELEASE
          description: A solid description for this dependency

If you add this configuration and search for "acme" (or "solid"), you’ll find this extra entry; generating a maven project with it should add the following to the pom:

<dependency>
    <groupId>com.example.acme</groupId>
    <artifactId>acme</artifactId>
    <version>1.2.0.RELEASE</version>
</dependency>

The rest of this section will detail the other configuration options.

7.4.1 Availability (version range)

By default, a dependency is available regardless of the Spring Boot version you have selected. If you need to restrict a dependency to a certain Spring Boot generation you can add a versionRange attribute to its definition. A version range is a range of versions of Spring Boot which are valid in combination with it. The versions are not applied to the dependency itself, but rather used to filter out the dependency, or modify it, when different versions of Spring Boot are selected for the generated project.

A typical version is composed of four parts: a major revision, a minor revision, a patch revision and a qualifier. Qualifiers are ordered as follows:

  • M for milestones (e.g. 2.0.0.M1 is the first milestone of the upcoming 2.0.0 release): can be seen as "beta" release
  • RC for release candidates (e.g. 2.0.0.RC2 is the second release candidate of upcoming 2.0.0 release)
  • RELEASE for general availability (e.g. 2.0.0.RELEASE is 2.0.0 proper)
  • BUILD-SNAPSHOT for development build (2.1.0.BUILD-SNAPSHOT represents the latest available development build of the upcoming 2.1.0 release).
[Tip]Tip

snapshots are in a bit special in that scheme as they always represents the "latest state" of a release. M1 represents the most oldest version for a given major, minor and patch revisions.

A version range has a lower and an upper bound, and if the bound is inclusive it is denoted as a square bracket ([ or ]), otherwise it is exclusive and denoted by a parenthesis (( or )). For instance [1.1.6.RELEASE,1.3.0.M1) means from all versions from 1.1.6.RELEASE up to but not including 1.3.0.M1 (concretely no including the 1.3.x line and after).

A version range can be a single value, e.g. 1.2.0.RELEASE, which is short for "this version or greater". It is an inclusive lower bound with an implied infinite upper bound.

If you need to specify "the latest release" in a given line, you can use a x rather than an hard-coded version. For instance, 1.4.x.BUILD-SNAPSHOT is the latest snapshot build of the 1.4.x line. For instance, if you want to restrict a dependency from 1.1.0.RELEASE to the latest stable release of the 1.3.x line, you’d use [1.1.0.RELEASE,1.3.x.RELEASE].

Snapshots are naturally ordered higher than released versions, so if you are looking to match a dependency to only the latest snapshots of Spring Boot, you could use a version range of 1.5.x.BUILD-SNAPSHOT (assuming 1.5 was the latest).

[Tip]Tip

Remember to quote the values of a version range in YAML configuration files (with double quotes "").

See below in the section on linking versions for more examples and idioms.

7.4.2 Repository

If the dependency is not available on Maven Central (or whatever default repository that is configured on your end), you can also add a reference to a repository. A repository is declared at the top level (under env) and given an id via the key in the configuration:

initializr:
  env:
    repositories:
      my-api-repo-1:
        name: repo1
        url: http://example.com/repo1

Once defined, the repository can then be referred back to in a dependency

initializr:
  dependencies:
    - name: Other
      content:
        - name: Foo
          groupId: org.acme
          artifactId: foo
          version: 1.3.5
          repository: my-api-repo-1

It is usually preferable to have a BOM for every dependency, and attach the repository to the BOM instead.

[Tip]Tip

The snapshots and milestones repositories on repo.spring.io are automatically available with the spring-snapshots and spring-milestones identifiers respectively.

7.5 Configuring Bill of Materials

A Bill of Materials (BOM) is a special pom.xml, deployed to a Maven repository, and used to control dependency management for a set of related artifacts. In the Spring Boot ecosystem we usually use the suffix -dependencies on the artifact id of a BOM. In other projects we see -bom. It is recommended that all dependencies are included in a BOM of some sort, since they provide nice high level features for users of the dependency. It is also important that 2 BOMs used in a project do not contain conflicting versions for the same dependency, so the best practice is to look at the existing BOMs in the Initializr before you add a new one, and make sure that you aren’t adding a conflict.

In the Initializr a BOM is declared at the env level, and given an id through the configuration key. Example:

initializr:
  env:
    boms:
      my-api-bom:
        groupId: org.acme
        artifactId: my-api-dependencies
        version: 1.0.0.RELEASE
        repositories: my-api-repo-1

If a BOM requires a special, non-default repository, then it can be referred to here, instead of having to explicitly list the repository again for each dependency. A dependency, or a dependency group, can declare that it requires the use of one or more BOMs by referring to the id:

initializr:
  dependencies:
    - name: Other
      content:
        - name: My API
          id : my-api
          groupId: org.acme
          artifactId: my-api
          bom: my-api-bom

7.5.1 Map coordinates according to the Spring Boot version

In addition to a Spring Boot version range for the dependency or a BOM, you can configure the version relationships at a finer grained level using version mappings. A dependency or BOM has a list of "mappings", each of which consists of a version range, and a set of one or more dependency properties to override for those versions of Spring Boot. You can use a mapping to switch the version of a dependency, or (better) the BOM, or to change its artifact id (if the project changed its packaging) for instance.

Here’s an example of a BOM with mappings:

initializr:
  env:
    boms:
      cloud-bom:
        groupId: com.example.foo
        artifactId: acme-foo-dependencies
        mappings:
          - versionRange: "[1.2.3.RELEASE,1.3.0.RELEASE)"
            version: Arcturus.SR6
          - versionRange: "[1.3.0.RELEASE,1.4.0.RELEASE)"
            version: Botein.SR7
          - versionRange: "[1.4.0.RELEASE,1.5.x.RELEASE)"
            version: Castor.SR6
          - versionRange: "[1.5.0.RELEASE,1.5.x.BUILD-SNAPSHOT)"
            version: Diadem.RC1
            repositories: spring-milestones
          - versionRange: "1.5.x.BUILD-SNAPSHOT"
            version: Diadem.BUILD-SNAPSHOT
            repositories: spring-snapshots,spring-milestones

The primary use case here is to map Spring Boot versions to the preferred or supported versions of the Foo project. You can also see that for the milestone and snapshot BOMs, additional repositories are declared because those artifacts are not in the default repository.

[Tip]Tip

We also use the x trick in version ranges to avoid updating the range every time a new Spring Boot 1.5 bug fix release is available

See below in the section on linking versions for more examples.

7.5.2 Aliases

A dependency has an id (e.g. "web-services"), but it could be necessary to provide a new id and still be able to serve request from client using the now deprecated id. To do so, an alias can be defined for ths dependency;

initializr:
  dependencies:
    - name: Other
      content:
        - name: Web Services
          id: web-services
          aliases:
            - ws

The same project can now be generated with dependencies=ws or dependencies=web-services.

7.5.3 Facets

A "facet" is a label on a dependency which is used to drive a code modification in the generated project. In the standard Initializr generator, there is only one facet that is actually used (web), but custom installations might choose to use it for their own purposes. The web facet is used to drive the inclusion of spring-boot-starter-web if any other dependency with that facet is included. The value of the "facets" property of a dependency is a list of strings.

7.5.4 Links

Links can be used to provide descriptive and hyperlink data to guide to user on how to learn more about a dependency. A dependency has a "links" property which is a list of Link. Each link has a rel label to identify it, an href and an optional (but recommended) description.

The following rel value are currently officially supported:

  • guide: the link points to a guide describing how to use the related dependency. It can be a tutorial, a how-to or typically a guide available on spring.io/guides
  • reference: the link points to a section of a developer guide typically or any page that documents how to use the dependency

The url can be templated if its actual value can change according to the environment. An URL parameter is specified with curly braces, something like example.com/doc/{bootVersion}/section defines a bootVersion parameter.

The following attributes are currently supported:

  • bootVersion: the Spring Boot version that is currently active

Here is an example that adds two links to the acme dependency:

initializr:
  dependencies:
    - name: Tech
      content:
        - name: Acme
          id: acme
          groupId: com.example.acme
          artifactId: acme
          version: 1.2.0.RELEASE
          description: A solid description for this dependency
          links:
            - rel: guide
              href: https://com.example/guides/acme/
              description: Getting started with Acme
            - rel: reference
              href: http://docs.example.com/acme/html

7.5.5 Improve search results

Each dependency can have a weight (a number >=0) and also keywords (list of string) that are used to prioritize them in the search feature in the web UI. If you type one of the keywords into the "Dependencies" box in the UI, those dependencies will be listed below, in order of decreasing weight, if they have one (unweighted dependencies come last).