SpringBoot custom starter and automatic configuration

The core of spring boot is automatic configuration, and the starter projects support automatic configuration. In addition to the official starter, users can also customize their own starter projects according to the rules.

Custom starter conditions

The automation configuration shall meet the following conditions:

  • Check the corresponding classes under the classpath according to the conditions, that is to say, you need to provide the corresponding checkable classes;
  • When the conditions are met, the defined Bean can be generated and registered in the container;
  • Be able to automatically configure the configuration required by the project;

Custom spring boot starter

Here, we use maven project management tool to create the starter. First we need to create a simple maven project. Here we take the integration of a SMS service as an example to create a project.

Create maven project

To create a simple maven project, the specific steps are omitted. It can be created by IDE such as intellj idea or by maven command.

The directory structure is as follows:

.
├── pom.xml
├── spring-boot-starter-msg.iml
└── src
    ├── main
    └── test

The introduction of spring boot automation configuration in pom.xml depends on spring boot autoconfigure:

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

Define Service service class

The definition of Service service class has two functions: one is the functional Service of the introduced project in the province, and the other is the judgment basis for spring boot automatic configuration.

A class of MsgService is defined here.

package com.secbro2.msg;

import com.secbro2.utils.HttpClientUtils;

public class MsgService {

	/**
	 * Access the url address of sending SMS
	 */
	private String url;

	/**
	 * Request keyId provided by SMS service provider
	 */
	private String accessKeyId;

	/**
	 * KeySecret provided by SMS service provider
	 */
	private String accessKeySecret;

	public MsgService(String url, String accessKeyId, String accessKeySecret) {
		this.url = url;
		this.accessKeyId = accessKeyId;
		this.accessKeySecret = accessKeySecret;
	}

	public int sendMsg(String msg) {
		// Call http service and send message, return result
		return HttpClientUtils.sendMsg(url, accessKeyId, accessKeySecret, msg);
	}

	// Omit getter/setter methods
}

Among them, MsgService uses a tool class HttpClientUtils. Only the requested parameter information is simply printed in HttpClientUtils.

package com.secbro2.utils;

public class HttpClientUtils {

	public static int sendMsg(String url, String accessKeyId, String accessKeySecret, String msg) {
		//TODO calls the specified url to request the business logic
		System.out.println("Http Request url=" + url + ";accessKeyId=" + accessKeyId + ";accessKeySecret=" + accessKeySecret + ";msg=" + msg);
		return 0;
	}
}

Define configuration class

Define the MsgProperties configuration class to encapsulate the basic configuration in application.properties or application.yml. Here, the configuration prefix of SMS sending is msg.

@ConfigurationProperties(prefix = "msg")
public class MsgProperties {

	/**
	 * Access the url address of sending SMS
	 */
	private String url;

	/**
	 * Request keyId provided by SMS service provider
	 */
	private String accessKeyId;

	/**
	 * KeySecret provided by SMS service provider
	 */
	private String accessKeySecret;
	
	// Other parameter definitions
	// Omit getter/setter methods

}

The @ ConfigurationProperties annotation is used to assemble the corresponding properties.

Create automation configuration class

Autoconfig class is a common java class, which is given different functions by different annotations. Of course, the core is the @ Configuration annotation.

@Configuration
@ConditionalOnClass(MsgService.class)
@EnableConfigurationProperties(MsgProperties.class)
public class MsgAutoConfiguration {

	/**
	 * Injection property configuration class
	 */
	@Resource
	private MsgProperties msgProperties;

	@Bean
	@ConditionalOnMissingBean(MsgService.class)
	@ConditionalOnProperty(prefix = "msg", value = "enabled", havingValue = "true")
	public MsgService msgService() {
		MsgService msgService = new MsgService(msgProperties.getUrl(), msgProperties.getAccessKeyId(),
				msgProperties.getAccessKeySecret());
		// If other set methods are provided, you can call the corresponding methods here to set or initialize them accordingly.
		return msgService;
	}
}

Annotation on MsgAutoConfiguration class, @ Configuration is used to declare that this class is a Configuration class@ The ConditionalOnClass annotation indicates that the MsgService class will be instantiated only when it exists in the classpath; @ EnableConfigurationProperties sets the corresponding property configuration in application.properties to the MsgProperties object;

Annotation on the msgService method, @ Bean indicates that the object instantiated by the method will be loaded into the container@ ConditionalOnMissingBean indicates to instantiate when there is no MsgService object in the container; @ ConditionalOnProperty specifies msg.enabled in the configuration file =true to instantiate.

Add spring.factories

When all the basic code and autoconfig classes are ready, they need to be registered. This is the familiar META-INF/spring.factories configuration file. Of course, this needs to be created in your own project.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.secbro2.msg.MsgAutoConfiguration

Register the MsgAutoConfiguration class in the spring.factories configuration file. If there are more than one autoconfig class, just separate the lines with commas.

At this point, an automatic configuration starter based on Spring Boot is completed. Use "maven:install" to package it to the local maven warehouse or upload it to the private server. Other projects can then be used through maven dependencies.

starter project use

In other projects, the dependency is introduced through the following dependency.

<dependency>
    <groupId>com.secbro2</groupId>
    <artifactId>spring-boot-starter-msg</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

Then configure the corresponding parameters in the application.properties of the current project:

msg.enabled=true
msg.url=127.0.0.1
msg.accessKeyId=10001
msg.accessKeySecret=afelwjfwfwef

For example, if other projects are also Spring Boot projects, you can define a simple Controller for testing.

@RestController
public class HelloWorldController {

	@Resource
	private MsgService msgService;

	@RequestMapping("/sendMsg")
	public String sendMsg(){
		msgService.sendMsg("Test message");
		return "";
	}
}

When accessed through a browser: When http://localhost:8080/sendMsg, the following log will be printed:

Http request, url = 127.0.0.1; accesskeyid = 10001; accesskeysecret = afelwjffwfef; MSG = test message

The MsgService object is automatically configured and the test passes.

For starter s such as SMS sending, it can be further expanded to realize various basic functions of SMS sending. When other projects need, they can only use the corresponding dependency and configure specific parameters immediately. Isn't it very convenient?

Summarize the workflow of Starter:

  • Spring Boot scans the JAR packages that the project depends on when it starts, looking for the JAR packages containing the spring.factories file;
  • Load the AutoConfiguration class according to the spring.factories configuration;
  • Automatically configure and inject the Bean into the Spring container according to the conditions of @ Conditional annotation.

New vision of < center > < b > program

Tags: Spring Maven xml Java

Posted on Wed, 06 Nov 2019 20:56:01 -0500 by mrgrammar