實現本身的springboot starter

爲何能夠自定義starter?

固然是spring官方提供了相應的接口,讓第三方本身去集成springboot,由於spring官方的人員不可能提供全部的starter,可是不知道爲何Druid不是spring官方集成的?java

我爲何去探究springboot starter呢?

我考慮的是springboot提到的是默認包掃描路徑是啓動類的子包,那麼加入的這些starter顯然不是在這個路徑下,爲何能夠被spring管理呢,這些starter作了什麼操做。在研究完了springboot starter後,就有了這個自定義的car-spring-boot-starter。web

實現本身的car-spring-boot-starter

項目概要描述

這裏會涉及到兩個maven工程,springboot-starter-car和springboot-starter-test-car,第一個是咱們要構建的starter,第二個是springboot工程用於測試咱們的starter是否能正常使用。spring

工程目錄截圖apache

springboot-starter-car工程目錄                      springboot的測試工程目錄springboot

構建springboot-starter-car工程

1.建立maven工程,引入maven依賴app

<?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.建立CarProperties類,該類就是一個接受配置的pojo,使用@ConfigurationProperties(prefix = "car")指定了接受配置文件參數的前綴eclipse

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.建立CarService類,該類是這個starter對外所提供的服務,這裏僅提供獲取價格和重量的服務maven

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.建立自動配置類CarAutoConfiguration,主要是將配置文件的信息讀取到CarProperties中,並將CarService服務實例化。代碼中已經給了詳細解釋,就再也不贅述。spring-boot

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;  
    }  
}

這裏再提一點就是這個類可能用到的註解測試

@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.在src/main/resources新建META-INF文件夾,在META-INF文件夾下新建spring.factories文件,寫入

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

spring.factories的內容是給springboot啓動時讀取的。固然也可使用註解方式代替該文件,在啓動類上添加@ImportAutoConfiguration({CarAutoConfiguration.class}) 。

6.使用maven命令打包,eclipse能夠直接使用以下方式打包並安裝到本地maven庫

7.測試,新建一個springboot項目springboot-starter-test-car,引入pom依賴

<?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.建立測試接口 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.這裏貼一下 application.properties的內容

car.price=100
car.weight=1000

10.啓動項目,訪問http://localhost:8080/get/price ,能獲得配置文件中的值,就說明starter建立成功。

相關文章
相關標籤/搜索