Customizing Spring Boot Starters
Introduction
One of the most powerful features of Spring Boot is the ability to extract common scenarios into custom starters. These starters allow us to provide a specific set of configurations for a particular scenario, making it easier to use Spring Boot. However, not all usage scenarios can be included in the default starters, and that’s where customizing the starters comes in.
How to Customize a Starter
To customize a starter, we need to write an automatic configuration module that will provide the necessary configurations for our scenario. We can refer to the @WebMvcAutoConfiguration example to see what we need to prepare. Here’s an excerpt from the code:
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean({ WebMvcConfigurationSupport.class })
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
@Import({ WebMvcAutoConfiguration.EnableWebMvcConfiguration.class })
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
@Bean
@ConditionalOnBean({ View.class })
@ConditionalOnMissingBean
public BeanNameViewResolver beanNameViewResolver() {
BeanNameViewResolver resolver = new BeanNameViewResolver();
resolver.setOrder(2147483637);
return resolver;
}
}
}
We can extract some custom configuration and create a new starter. To do this, we need to create a new module that will provide the necessary configurations for our scenario.
Creating a Custom Starter
To create a custom starter, we need to create a new module that will provide the necessary configurations for our scenario. We can use the spring-boot-starter as a reference to see how it’s structured.
Here’s an excerpt from the spring-boot-starter pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
We can see that it introduces the spring-boot-autoconfigure module, which provides the necessary auto-configuration for the starter.
Here’s an excerpt from the spring-boot-autoconfigure pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
We can see that it provides the necessary auto-configuration for the starter.
Custom Starter Example
Let’s create a custom starter called hello-spring-boot-starter that will provide a simple “hello” service. We can create a new module that will provide the necessary configurations for our scenario.
Here’s an excerpt from the hello-spring-boot-starter pom.xml:
<dependency>
<groupId>com.gf</groupId>
<artifactId>hello-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
We can see that it introduces the hello-spring-boot-starter-autoconfigurer module, which provides the necessary auto-configuration for the starter.
Here’s an excerpt from the hello-spring-boot-starter-autoconfigurer pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
We can see that it provides the necessary auto-configuration for the starter.
Testing the Custom Starter
To test the custom starter, we can create a new project called hello-spring-boot-starter-test that will use the custom starter. We can add the custom starter to the project’s pom.xml:
<dependency>
<groupId>com.gf</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
We can see that it introduces the custom starter to the project.
Here’s an excerpt from the HelloController class:
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello/{name}")
public String hello(@PathVariable(value = "name") String name) {
return helloService.sayHello(name + ",");
}
}
We can see that it uses the custom starter to provide the necessary configurations for the service.
Here’s an excerpt from the application.properties file:
gf.hello.prefix = hi
gf.hello.suffix = what's up man?
We can see that it provides the necessary configurations for the custom starter.
When we run the project and visit http://127.0.0.1:8080/hello/zhangsan, we can see the following result:
hi-zhangsan, what's up man?
We can see that the custom starter is working correctly and providing the necessary configurations for the service.