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!
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.
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>
This is the basic skeleton of our project.
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.
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.
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;
}
}
-
@Configuration
indicates that this is a configuration class -
@EnableConfigurationProperties(CodemanProperties.class)
Because I used
ConfigurationProperties
in theCodemanProperties
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.
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.
After writing our configuration class, let's test it.
- 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
- 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>
- Write a simple service.
- Add some more configuration information.
- Finally start our server
As you can see, our starter does play a role, codemanService is automatically registered to our project.
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.