Skip to content

Instantly share code, notes, and snippets.

@codeman688
Last active June 28, 2019 11:01
Show Gist options
  • Save codeman688/e07f07ff41c55a79f557bb984946258b to your computer and use it in GitHub Desktop.
Save codeman688/e07f07ff41c55a79f557bb984946258b to your computer and use it in GitHub Desktop.

Implement a simple SpringBoot-Starter

We use Spring Boot, which is basically intoxicated by the convenience of its Staters. Starter brings us a lot of automation configuration, with these automated configurations, we can build a production-level development environment with little effort, and some friends will think this Starter is amazing! In fact, Starter is also the basic knowledge point in Spring. Today, codeman will implement a Starter with you, slowly revealing the mystery of Starter!

Core knowledge

A starter generally contains the following:

  • A configuration class annotated with @ConfigurationProperties

    This class is used to dynamically read the user's configuration information.

  • A class that turns on automatic configuration

    SpringBoot will enable automatic configuration through this configuration class. We will discuess details later. Then we usually add a @Conditional annotation to the auto-configuration class so that when certain conditions are met, auto-configuration is turned on, and in some cases auto-configuration is not turned on.

  • a class that performs a specific function

    Our starter will eventually have to provide some services. So we have to write a real service-providing class, which is usually registered as a bean.

Then, if you are not familiar with the annotations I mentioned earlier, you can go here:

https://github.com/codeman-cs/SpringBoot/wiki/An-overview-of-25-Spring-Boot-core-annotations

Before reading the following article, you need to master the usage of these annotations.

In Action

The so-called Starter is actually a normal Maven project. So if we want to customize the Starter, we need to first create a normal Maven project. After the creation is complete, add the following dependencies.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

20190628163106

This is the basic skeleton of our project.

Create our configuration class

package com.github.codeman.mystarter;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "codeman")
public class CodemanProperties {
    private static final String DEFAULT_NAME = "codeman";
    private static final String DEFAULT_MSG = "learn program in a better way";

    private String name = DEFAULT_NAME;
    private String msg = DEFAULT_MSG;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

This configuration class is very simple, @ConfigurationProperties(prefix = "codeman") will automatically read the configuration properties starting with codeman in application.properties. In the future, the codeman.name and codeman.msg that we configured in applicaton.properties will be read in and assigned to the corresponding properties.

Create our function class

A starter always has to do something specific. Here I write the simplest service class, which can be very complicated in actual projects.

public class CodemanService {
    private String msg;
    private String name;
    public String sayHello() {
        return name + " say " + msg + " !";
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

This service class doesn't do anything special. It will be registered as a bean later.

Automatic configuration class

Here is the point, our automatic configuration class is like this.

@Configuration
@EnableConfigurationProperties(CodemanProperties.class)
@ConditionalOnClass(CodemanService.class)
public class CodemanServiceAutoConfiguration {
    @Autowired
    CodemanProperties codemanProperties;

    @Bean
    CodemanService codemanService() {
        CodemanService codemanService = new CodemanService();
        codemanService.setMsg(codemanProperties.getMsg());
        codemanService.setName(codemanProperties.getName());
        return codemanService;
    }
}

20190628163712

  • @Configuration indicates that this is a configuration class

  • @EnableConfigurationProperties(CodemanProperties.class)

    Because I used ConfigurationProperties in the CodemanProperties class, we have a matching @EnableConfigurationProperties here.

  • Implementation

    Then we register our CodemanService as a bean in the configuration class, so that other modules can use our CodemanService directly when they using our module.

But you may have noticed, I also wrote this annotation. @ConditionalOnClass(CodemanService.class)

Its semantics is that when the CodemanService class is present, automatic configuration is enabled, otherwise the class does not work.

Of course you can also add the following annotations:

  • @ConditionalOnProperty

    Combine @Conditional annotations to enable configuration when the specified property has a specified value.

  • @ConditionalOnExpression

    Combine @Conditional annotations to enable configuration when the SpEL expression is true.

You can also not write any @Conditional annotations. If so, your configuration class will always be enabled.

Registration configuration class

In the final step, in order for our auto-configuration class to work, we need to register it in a specific way.

SpringBoot convention: Springboot will first check the spring.factories file in the META-INF folder and read the following field. In short, just write it as follows.

20190628164028

Implementation

After writing our configuration class, let's test it.

  1. Install to local

By executing this command directly in the root directory of the current project, you can package the current module into a jar file and install it locally.

$ mvn install
  1. Create a new project to test

Then create a new SpringBoot project and then add this dependency.

        <dependency>
            <groupId>com.github.codeman</groupId>
            <artifactId>mystarter</artifactId>
            <version>0.0.1</version>
        </dependency>
  1. Write a simple service.

20190628170603

  1. Add some more configuration information.

20190628171158

  1. Finally start our server

20190628162759

As you can see, our starter does play a role, codemanService is automatically registered to our project.

Summary

Then if you want to write your own starter, you should give it a modification:

  • CodemanService

   This is the class that will do your real work.

  • CodemanProerties

   You will read the user's configuration information through this configuration class.

  • change @Conditional

   Depending on when you want to turn on automatic configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment