Every good Spring Boot project usually starts at start.spring.io/

– Josh Long

In general, when many customized modules need to be maintained in my own project or my company’s project, they are uploaded to maven private server for easy use. However, there is a problem. Every time you need the relevant package, you need to refer to the document or BOM, which cannot be directly introduced when the project is under construction. Try to build my own Spring Initializr service, and integrate some of my own packages to provide personalized services and rapid development.

The target

The basic framework

  • Spring Initializr provides a core REST API that can be integrated into a UI or IDE (such as Intellij IDEA) to generate projects directly
  • Start.spring. IO provides a Web interface that is strongly dependent on Spring Initializr, displays data from Spring Properties, and is customized using SPI provided by Spring Initializr
  • In addition, Spring. IO provides Spring Boot Metadata endpoint, and Spring Initializr uses metadata as an external data source to ensure that the generated Spring Boot version is up to date

personalized

Start.spring. IO/Although spring Boot start is already provided, some customization is still required in certain scenarios, such as:

  1. Due to network limitations, you need to build your own instance
  2. Customize your OWN UI
  3. Provide some of your own configurations or dependencies, such as an internal company starter

Spring Initializr is a modular application built with Spring Boot, so it’s easy to extend

version

Since the official Spring Initializr provided BOM, we could directly build based on the latest BOM version.

<dependencyManagement> <dependencies> <dependency> <groupId>io.spring.initializr</groupId> < artifactId > initializr - bom < / artifactId > < version > 0.8.0. RELEASE < / version > < type > pom < type > the < scope > import < / scope > </dependency> </dependencies> </dependencyManagement>Copy the code

Set up process

To prepare

Two components

  • Github.com/spring-io/i…

  • Github.com/spring-io/s…

Initializr is required and the UI interface is optional.

personalized

Customizing profiles

You can define application.yml based on InitializrProperties to produce core dependencies. Spring Initializr also allows us to use InitializrMetadataProvider define the metadata, as a result, we can create a CustomInitializrProperties class to read the configuration items of different configuration files.

@Configuration
@EnableConfigurationProperties(CustomInitializrProperties.class)
public class CustomInitializrConfiguration {

  @Bean
  public DefaultInitializrMetadataProvider customInitializrMetadataProvider(InitializrProperties initializrProperties,
      CustomInitializrProperties customInitializrProperties,
      InitializrMetadataUpdateStrategy initializrMetadataUpdateStrategy) {
    InitializrMetadata meta = InitializrMetadataBuilder.fromInitializrProperties(customInitializrProperties.getInitializr())
        .withInitializrProperties(initializrProperties, true).build();
    return new DefaultInitializrMetadataProvider(meta, initializrMetadataUpdateStrategy);
  }
}


@Data
@ConfigurationProperties("custom")
public class CustomInitializrProperties {
  @NestedConfigurationProperty
  InitializrProperties initializr = new InitializrProperties();
}Copy the code

The configuration is loaded by StartApplication, but since the application does not use component scanning, we need to customize the configuration file:

custom:
  initializr:
    dependencies:
      - name: Custom Dependencies
        content:
          - name: Custom dependency
            id: custom-dependency
            groupId: your.domain
            artifactId: custom-artifact
            starter: false
            description: My first custom dependency for the Spring InitializrCopy the code

With this custom dependency configuration, we can control the order in which configuration items are merged and displayed.

Initializr extension

Customizing dependencies through configuration files is not always enough. Sometimes we need to customize snippets of code. In this case, we need to use some of the extension hooks provided by Spring Initializr:

  • BuildCustomizer: Define the Maven/Gradle build process, such as adding Maven build plug-ins
  • ProjectContributor: Defines some personalized project directories or files
  • MainSourceCodeCustomizer, MainCompilationUnitCustomizer, MainApplicationTypeCustomizer, TestSourceCodeCustomizer, TestApplicationTypeCustomizer: project source code to generate or change, but not limited to program language
  • GitIgnoreCustomizer: Defines the gitignore file
  • HelpDocumentCustomizer: Define help.md file
  • ProjectDescriptionCustomizer: commonly used to adapt the project description, such as automatic solution framework version and invalid combination of language level.

For example, if we needed to add maven plug-ins to our build project, we would need to use a so-called “pseudo dependency.” First we need to define a dependency that looks like this:

custom:
  initializr:
    dependencies:
      - name: Custom Dependencies
        content:
          - name: Custom Maven Plugin
            id: custom-maven-plugin
            groupId: your.domain
            artifactId: custom-maven-plugin
            version: 1.0.0
            starter: false
            description: Configures custom Maven plugin integration for project scansCopy the code

Next, we define two BuildCustomizers: one to add maven dependencies and one to remove them.

@ProjectGenerationConfiguration @ConditionalOnRequestedDependency("custom-maven-plugin") public class CustomMavenPluginConfiguration { @Bean public BuildCustomizer<MavenBuild> customPluginConfigurer() { return (MavenBuild build) -> { build.dependencies().ids().filter(it -> it.equals("custom-maven-plugin")) .findFirst() .map(r -> build.dependencies().get(r)).map(r -> { build.plugins().add(r.getGroupId(), r.getArtifactId(), (plugin) -> plugin.execution("my-execution", (first) -> first.goal("scan").configuration((conf) -> {conf.add("failOnSeverity", "MAJOR"); }))); return build; }).orElse(build); }; } @Bean public BuildCustomizer<MavenBuild> customPluginDependencyRemoval() { return build -> build.dependencies().remove("custom-maven-plugin"); }}Copy the code

Note that using annotations, Spring Initializr does not use these automated configurations itself, but rather when building the project, but requires spring.Factories to register these configurations

io.spring.initializr.generator.project.ProjectGenerationConfiguration=\
  io.spring.start.site.extension.StartProjectGenerationConfiguration, \
  io.spring.start.site.CustomMavenPluginConfigurationCopy the code

The resulting POM looks something like this:

. < plugin > < groupId > your domain < / groupId > < artifactId > custom maven - plugin < / artifactId > < version > 1.0.0 < / version > <executions> <execution> <id>my-execution</id> <goals> <goal>scan</goal> </goals> <configuration> <failOnSeverity>MAJOR</failOnSeverity> </configuration> </execution> </executions> </plugin>Copy the code

conclusion

This article has provided a brief introduction to some of Spring Initializr’s customizations, but you need to discover more and better extensions.

This article is written BY misguided Lao Nong and licensed BY CC BY 4.0CN. It can be reproduced and quoted freely, but the author must be signed and indicate the source of the article.