Implement your own springboot starter

Why can the starter be customized?

Of course, spring officially provides the corresponding interface, so that the third party can integrate springboot, because it is impossible for the official spring personnel to provide all the starters, but I don't know why Druid is not officially integrated by spring?

Why should I explore springboot starter?

What I consider is that springboot mentioned that the default package scanning path is a subpackage of the startup class, so the starters added are obviously not in this path, why can they be managed by spring, and what operations do these starters do. After studying the springboot starter, there is this custom car-spring-boot-starter.

Implement your own car-spring-boot-starter

Project Summary Description

Two maven projects will be involved here, springboot-starter-car and springboot-starter-test-car. The first is the starter we want to build, and the second is the springboot project to test whether our starter can be used normally.

Project directory screenshot

springboot-starter-car project directory springboot test project directory

Build the springboot-starter-car project

1. Create a maven project and introduce maven dependencies

<?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.lzy.springboot.starter.car</groupId>
	<artifactId>car-springboot-starter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	<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-autoconfigure</artifactId>
			<version>1.5.2.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<version>1.5.2.RELEASE</version>
			<optional>true</optional>
		</dependency>
	</dependencies>

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

2. Create the CarProperties class, which is a pojo that accepts configuration. Use @ConfigurationProperties(prefix = "car") to specify the prefix that accepts configuration file parameters

package com.lzy.springboot.starter.car;

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

/**
 * 接受配置文件的pojo
 * 
 * @author admin
 *
 */
// 定义application.properties配置文件中的配置前缀
@ConfigurationProperties(prefix = "car")
public class CarProperties {

	// 价格
	private int price;
	// 重量
	private int weight;

	get/set方法省略
}

3. Create the CarService class, which is the service provided by this starter to the outside world, here only provides services for obtaining price and weight

package com.lzy.springboot.starter.car.service;  
  
import com.lzy.springboot.starter.car.CarProperties;  
/**
 * 引入该starter后,通过配置文件的信息可以提供什么功能
 * 
 * @author admin
 *
 */
public class CarService {  
      
    private CarProperties properties;  
      
    public CarService(CarProperties properties){  
        this.properties = properties;  
    }  
      
    public CarService(){  
          
    }  
      
    public int getCarPrice(){  
        return properties.getPrice();  
    }  
      
    public int getCarWeight(){  
        return properties.getWeight();  
    }  
      
    
}  

4. Create an automatic configuration class CarAutoConfiguration, mainly to read the information of the configuration file into CarProperties, and instantiate the CarService service. The code has already given a detailed explanation, so I won't repeat it.

package com.lzy.springboot.starter.car.conf;


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

import com.lzy.springboot.starter.car.CarProperties;
import com.lzy.springboot.starter.car.service.CarService;
// 配置注解  ,标记该类是个配文类
@Configuration 
// 开启指定类的配置,既是接受配置文件中的参数的类, 多个时我们可以这么写value={Properties1.class,Properteis2.class....}
@EnableConfigurationProperties(CarProperties.class) 
// 当这个类(CarService)在classPath下,并且容器 中没有相同的,就自动配置 
@ConditionalOnClass(CarService.class)
// 表示只有我们的配置文件是否配置了以car为前缀的资源项值,并且在该资源项值为enabled,如果没有配置我们默认设置为enabled
@ConditionalOnProperty(prefix="car", value="enabled", matchIfMissing=true)
public class CarAutoConfiguration {  
    @Autowired  
    private CarProperties properties;  
      
    @Bean  
    @ConditionalOnMissingBean(CarService.class)// 当容器中没有指定Bean的情况下,自动配置carService类  
    public CarService carService(){  
        CarService personService = new CarService(properties);  
        return personService;  
    }  
}  

One more point here is the annotations that this class may use

@ConditionalOnBean:当容器中有指定的Bean的条件下  
@ConditionalOnClass:当类路径下有指定的类的条件下  
@ConditionalOnExpression:基于SpEL表达式作为判断条件  
@ConditionalOnJava:基于JVM版本作为判断条件  
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置  
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下  
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下  
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下  
@ConditionalOnProperty:指定的属性是否有指定的值  
@ConditionalOnResource:类路径下是否有指定的资源  
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean  
@ConditionalOnWebApplication:当前项目是Web项目的条件下  

摘抄地址:https://blog.csdn.net/liuchuanhong1/article/details/55057135

5. Create a new META-INF folder in src/main/resources, create a new spring.factories file in the META-INF folder, and write

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lzy.springboot.starter.car.conf.CarAutoConfiguration

The content of spring.factories is read when springboot starts. Of course, you can also use annotation instead of this file to add @ImportAutoConfiguration({CarAutoConfiguration.class}) to the startup class.

6. Use the maven command to package, eclipse can be packaged and installed directly to the local maven library using the following methods

7. Test, create a new springboot project springboot-starter-test-car, and introduce pom dependencies

<?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.lzy.springboot.starter.car.test</groupId>  
    <artifactId>springboot-starter-car</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <packaging>jar</packaging>  
    <parent>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-parent</artifactId>  
        <version>1.5.1.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>  
          
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-web</artifactId>  
        </dependency>  
  
        <dependency>
        <!-- 引入car-springboot-starter -->  
            <groupId>com.lzy.springboot.starter.car</groupId>  
            <artifactId>car-springboot-starter</artifactId>  
            <version>0.0.1-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>  

8. Create a test interface PersonServiceController

package com.lzy.springboot.starter.car.controller;  
  
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lzy.springboot.starter.car.service.CarService;  
  
@RestController  
public class PersonServiceController {  
	// 自动注入starter中的carService  
    @Autowired 
    private CarService carService;  
      
    @GetMapping("/get/price")  
    public int getCarPrice(){ 
    	// 调用PersonService服务的方法
        return carService.getCarPrice();
    }  
      
    @GetMapping("/get/weight")  
    public int getCarWeight(){  
        return carService.getCarWeight(); 
    }  
}  

9. Start the project, visit http://localhost:8080/get/price, and if you can get the value in the configuration file, it means the starter was created successfully.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325241270&siteId=291194637