A list,

The most powerful function of SpringBoot is to extract common scenarios into a starter (scenario initiator). By introducing these scenario initiators provided by SpringBoot, we can use corresponding functions with a small amount of configuration. Even so, SpringBoot does not cover all of our usage scenarios, and we often need to customize the starter to simplify our use of SpringBoot.

How to customize the starter

Example 1.

How do I write automatic configuration?

Take @webMvCautoConfiguration as an example to see what needs to be prepared. Here is part of the code for WebMvcAutoConfiguration:

@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(a) {
            BeanNameViewResolver resolver = new BeanNameViewResolver();
            resolver.setOrder(2147483637);
            returnresolver; }}}Copy the code

We can extract some of the same configurations that we need when we customize our starter.

@Configuration  // Specify that this class is a configuration class
@ConditionalOnXXX  // The auto-configuration class takes effect when the specified condition is true
@AutoConfigureOrder  // Specify the order of the auto-configuration classes
@Bean  // Add components to the container
@ConfigurationProperties  // Bind the related configuration with the related xxxProperties
@EnableConfigurationProperties  // add xxxProperties to the containerTo be able to load the auto-configuration class, Configuration in the meta-inf/spring. Factories in org. Springframework. Boot. Autoconfigure. EnableAutoConfiguration = \ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\Copy the code

model

We looked at spring-boot-starter and found that there was no code:

We have a Springboot-starter in its dependency in the POM

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>
Copy the code

Spring-boot-starter has a spring-boot-autoconfigure

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
Copy the code

Some of the automatic configuration of the Web is written here, so we have the following summary:

The starter is only used for dependency management. If you need to write a configuration module similar to spring-boot-autoconfigure, you only need to introduce the starter to use automatic configurationCopy the code

Naming conventions

Official namespace

  • The prefix: spring – the boot – starter –
  • Mode: spring-boot-starter- Module name
  • For example, spring-boot-starter-web and spring-boot-starter- JDBC

Custom namespaces

  • Suffix: – spring – the boot – the starter
  • Mode: module-spring-boot-starter
  • Example: mybatis – spring – the boot – the starter

Customize the starter instance

We need to create two projects hello-spring-boot-starter and hello-spring-boot-starter-autoconfigurer

1. hello-spring-boot-starter

1.pom.xml

<?xml version="1.0" encoding="UTF-8"? >
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.gf</groupId>
	<artifactId>hello-spring-boot-starter</artifactId>
	<version>0.0.1 - the SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hello-spring-boot-starter</name>

	<! -- Initiator -->
	<dependencies>
		<! -- Introducing automatic configuration module -->
		<dependency>
			<groupId>com.gf</groupId>
			<artifactId>hello-spring-boot-starter-autoconfigurer</artifactId>
			<version>0.0.1 - the SNAPSHOT</version>
		</dependency>
	</dependencies>


</project>

Copy the code

Delete all files under the startup class, Resources, and test files.

2. hello-spring-boot-starter-autoconfigurer

1. pom.xml

<?xml version="1.0" encoding="UTF-8"? >
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.gf</groupId>
	<artifactId>hello-spring-boot-starter-autoconfigurer</artifactId>
	<version>0.0.1 - the SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hello-spring-boot-starter-autoconfigurer</name>
	<description>Demo project for Spring Boot</description>

	<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>
		<! -- Introducing spring-boot-starter, the basic combination of all starter -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

	</dependencies>


</project>

Copy the code

2. HelloProperties

package com.gf.service;

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

@ConfigurationProperties(prefix = "gf.hello")
public class HelloProperties {

    private String prefix;
    private String suffix;

    public String getPrefix(a) {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public String getSuffix(a) {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix; }}Copy the code

3. HelloService

package com.gf.service;


public class HelloService {

    HelloProperties helloProperties;

    public HelloProperties getHelloProperties(a) {
        return helloProperties;
    }

    public void setHelloProperties(HelloProperties helloProperties) {
        this.helloProperties = helloProperties;
    }

    public String sayHello(String name ) {
        return helloProperties.getPrefix()+ "-"+ name + helloProperties.getSuffix(); }}Copy the code

4. HelloServiceAutoConfiguration

package com.gf.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnWebApplication // Web should work
@EnableConfigurationProperties(HelloProperties.class)
public class HelloServiceAutoConfiguration {

    @Autowired
    HelloProperties helloProperties;

    @Bean
    public HelloService helloService(a) {
        HelloService service = new HelloService();
        service.setHelloProperties( helloProperties  );
        returnservice; }}Copy the code

5. spring.factories

“> < resources > < META-INF > spring.factories”

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gf.service.HelloServiceAutoConfiguration
Copy the code

Hello-spring-boot-starter-autoconfigurer, hello-spring-boot-starter, hello-spring-boot-starter, hello-spring-boot-starter

Test the custom starter

We created a hello-spring-boot-starter-test project to test our stater.

1. pom.xml

<?xml version="1.0" encoding="UTF-8"? >
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.gf</groupId>
	<artifactId>hello-spring-boot-starter-test</artifactId>
	<version>0.0.1 - the SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hello-spring-boot-starter-test</name>
	<description>Demo project for Spring Boot</description>

	<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-web</artifactId>
		</dependency>

		<! -- Introducing custom starter -->
		<dependency>
			<groupId>com.gf</groupId>
			<artifactId>hello-spring-boot-starter</artifactId>
			<version>0.0.1 - the SNAPSHOT</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>

Copy the code

2. HelloController

package com.gf.controller;

import com.gf.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    HelloService helloService;

    @GetMapping("/hello/{name}")
    public String hello(@PathVariable(value = "name") String name) {
        return helloService.sayHello( name + ","); }}Copy the code

3. application.properties

gf.hello.prefix = hi
gf.hello.suffix = what's up man ?
Copy the code

I run projects to http://127.0.0.1:8080/hello/zhangsan, the result is as follows:

hi-zhangsan , what's up man ? 
Copy the code

Download the source code: github.com/gf-huanchup…