Custom Spring Boot starter

When we use spring boot to develop applications quickly, we often introduce many libraries that start with spring boot starter,

I'll show you how to customize such a library to output logs (console, file or database)

The premise is that maven has been configured. Refer to https://my.oschina.net/u/154866/blog/3223749

1. New maven project, refer to the spring official website https://start.spring.io/ Fill in the basic information and select the library to depend on according to the actual situation

Then click the "GENERATE" button, and note that before generating, you can click the expand to preview the project structure

Then decompress the downloaded file and import it into a development tool (such as eclipse). It's very simple. Open eclipse and find the import button

The following prompt appears

Click next:

After finding the path, click the "OK" button, and the

Finally, click Finish to finish the import of maven project.

2. Officially enter the coding stage

Create a new package name, such as com.dongguangming , and then create sub packages respectively:

com.dongguangming.service, com.dongguangming.service.impl,
com.dongguangming.annotation,com.dongguangming.condition,com.dongguangming.autoconfigure

2.1 build log service interface

/**
 * 
 * @author dgm
 * @describe "Log service interface“
 */
public interface LogService {

    void print(String message);
}

2.2 realize the log service interface, which is divided into three implementations: console, file and database mysql

import com.dongguangming.service.LogService;

/**
 * @author dgm
 * @describe "Log to console“
 */
public class StdOutLogServiceImpl implements LogService {

	@Override
	public void print(String message) {
        System.out.println(message);
        System.out.println("Log to console!");
	}
}

/**
 * 
 * @author dgm
 * @describe "Log to file“
 */
public class FileLogServiceImpl implements LogService {

	private static final String FILE_NAME="d://LogService.txt";
	@Override
	public void print(String message) {
		try {
			File file = new File(FILE_NAME);
			FileWriter fw = null;
			// true: indicates the flag is appended
			fw = new FileWriter(file, true);
			fw.write(message+"\n");
			fw.close();

	        System.out.println(message);
			System.out.println("Write log to file!");
		} catch (IOException e) {
		}
	}
}

/**
 * @author dgm
 * @describe "Write log to mysql database“
 */
public class MysqlLogServiceImpl implements LogService {

	@Override
	public void print(String message) {
        System.out.println(message);
        System.out.println("Write log to database");
	}
}

2.3 create log type annotation

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;

import org.springframework.context.annotation.Conditional;

import com.dongguangming.condition.LogServiceTypeCondition;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Conditional(LogServiceTypeCondition.class)
public @interface LogServiceType
{
	//Where to output the log (console, file or mysql)
    String value() default "stdout";
}

2.4 write log by Condition condition judgment

import java.util.Map;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

import com.dongguangming.annotation.LogServiceType;

public class LogServiceTypeCondition implements Condition {

	    @Override
	    public boolean matches(ConditionContext conditionContext,
	    AnnotatedTypeMetadata metadata)
	    {
	        Map<String, Object> attributes = metadata.getAnnotationAttributes(LogServiceType.class.getName());
	        String type = (String) attributes.get("value");
	        System.out.println("value:"+type);
	        String enabledLogType = conditionContext.getEnvironment().getProperty("logType","StdOut");
	        System.out.println("enabledLogType:"+enabledLogType);

	        return (enabledLogType != null && type != null && enabledLogType.equalsIgnoreCase(type));
	    }
}

2.5 create auto configuration class

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import com.dongguangming.annotation.LogServiceType;
import com.dongguangming.service.LogService;
import com.dongguangming.service.impl.FileLogServiceImpl;
import com.dongguangming.service.impl.MysqlLogServiceImpl;
import com.dongguangming.service.impl.StdOutLogServiceImpl;

@Configuration
@ComponentScan
public class LogServiceAutoConfiguration
{
	@Bean
	@LogServiceType("STDOUT")
	@ConditionalOnMissingBean
    public LogService stdOutLogServiceImpl(){
        return new StdOutLogServiceImpl();
    }

    @Bean
    @LogServiceType("FILE")
    @ConditionalOnMissingBean
    public LogService fileLogServiceImpl(){
        return new FileLogServiceImpl();
    }
    
    @Bean
    @LogServiceType("MYSQL")
    @ConditionalOnMissingBean
    public LogService mysqlLogServiceImpl(){
        return new MysqlLogServiceImpl();
    }
}

2.6 create configuration file

Create the agreed configuration file in the directory src/main/resources /. First create the directory META-INF, and then create the very important configuration file in its directory spring.factories , fill in the following

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.dongguangming.autoconfigure.CustomAutoConfiguration,\
com.dongguangming.autoconfigure.LogServiceAutoConfiguration

In particular, the directory structure is contracted. The directory name must be named in this way, as well as the property configuration file name

There's no way. spring is so powerful that you can't be named blindly.

 

2.7 setting log type

Launch profile in project application.properties Log output type is set in logType=File

Then run the main program, the effect is as shown in the figure

2.8 packaging into jar

Use maven build tool to generate jar,

Then install the jar into the maven repository

2.9 reference the customized starter

Go back to the custom project's pom file and see the following information

Then the new project configuration dependency can be referenced just like other third-party starter s

 <!--Brought by the official website start,quite a lot-->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

<!--Remember, this is what I just customized starter-->
<dependency>
	<groupId>com.dongguangming</groupId>
	<artifactId>custom-logservice-spring-boot-starter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</dependency>

Then set the log type through the configuration file

#Note that there are three types of log output: stdout, file and mysql. Choose one of them
logType=File

Use this in code

@Autowired
LogService logService;

logService.print("Custom log output"));

At this point, the library of a custom starter is over. If you can, you can put the custom starter in each maven public / private server warehouse, so that the developers can refer to your dependency, but the official website has written a lot, I just give an example, because many people in the group don't know what the starter does.

All codes attached have been uploaded https://github.com/dongguangming/springboot-custom-starter

 

reference resources:

0.    Creating Your Own Auto-configuration

https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-developing-auto-configuration

Tags: Java Spring Maven MySQL

Posted on Mon, 25 May 2020 08:53:45 -0400 by jstgermain