最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解SpringBoot如何創(chuàng)建自定義Starter

 更新時間:2024年02月21日 10:45:22   作者:碼農(nóng)Academy  
Spring Boot的自動配置機制為開發(fā)人員提供了一種輕松集成和配置各種功能的便捷方式,本文將深入探討在Spring Boot中如何創(chuàng)建自定義Starter,為構建模塊化且易維護的應用提供有力的支持,需要的朋友可以參考下

Spring Boot的自動配置機制為開發(fā)人員提供了一種輕松集成和配置各種功能的便捷方式。然而,隨著項目的復雜性增加,更好地組織和分享通用功能變得至關重要。自定義Starter成為了理想的解決方案,旨在簡化項目的依賴管理和自動配置,使開發(fā)者能夠迅速而靈活地集成特定的功能模塊。本文將深入探討在Spring Boot中如何創(chuàng)建自定義Starter,為構建模塊化且易維護的應用提供有力的支持。

接下來我們來實現(xiàn)一個自定義的starter。

實現(xiàn)自定義Starter

首先,我們需要明確自定義starter的目標功能,如提供特定領域的服務或集成第三方庫。比如我們創(chuàng)建一個coderacademy-spring-boot-starter的starter,用于提供某些服務。例如我們的服務就實現(xiàn)一個打印功能:

public class CoderAcademyService {

    public String sayHello(){
        return "Hello 碼農(nóng)Academy!";
    }
}

本文旨在介紹如何自定義starter,故而starter的功能不是本文的主要內(nèi)容,后續(xù)我們會提供一個基于注解實現(xiàn)ES操作/搜索的服務的starter。感興趣的,點個關注哦~

創(chuàng)建項目結構

我們創(chuàng)建一個名為springboot-coderacademy-starter的項目,在pom.xml中設置groupId,artifactId還有version。其中groupIdartifactId應反映starter的名稱。

<groupId>com.springboot.coderacaemy</groupId>  
<artifactId>coderacermy-spring-boot-starter</artifactId>  
<version>1.0.0-SNAPSHOT</version>  
<packaging>jar</packaging>

然后我們在引入一些我們需要是用到的依賴,比如我們要使用@Configuration,@EnableConfigurationProperties等注解:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>

    <groupId>com.springboot.coderacaemy</groupId>
    <artifactId>coderacermy-spring-boot-starter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-starter</name>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

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

其中spring-boot-configuration-processor這個依賴主要用于IDEA支持和編譯時生成元數(shù)據(jù)。

本文使用的springboot版本為2.7.0

創(chuàng)建自動配置類

自動配置類負責定義Spring Boot應用程序中的通用配置和功能。這個類通常使用@Configuration注解進行標記,在這個類中注入服務、組件或其他你需要自動配置的對象。

import com.springboot.starter.coderacademy.service.CoderAcademyService;
import org.springframework.context.annotation.Configuration;

/**
 * @version 1.0
 * @description: <p></p >
 * @author: 碼農(nóng)Academy
 * @create: 2024/1/31 14:38
 */
@Configuration
public class CoderAcademyAutoConfig {

    @Bean
    public CoderAcademyService coderAcademyService(){
        return new CoderAcademyService();
    }
}

指定自動裝配類

resources文件夾下創(chuàng)建一個META-INF/spring.factories文件,在這個文件中指定自動裝配類CoderAcademyAutoConfig

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.springboot.starter.coderacademy.config.CoderAcademyAutoConfig

META-INF/spring.factories文件中,org.springframework.boot.autoconfigure.EnableAutoConfiguration是一個特殊的鍵,它的值是一個包含要應用的自動配置類的全限定名列表。當應用啟動時,SpringBoot的引導過程會掃描所有已引入jar包中的spring.factories文件,并根據(jù)EnableAutoConfiguration鍵下的類來加載和執(zhí)行相應的自動配置邏輯。

當然如果不使用這個配置,在調(diào)用方使用@ComponentScan也可以掃描到CoderAcademyAutoConfig。但是這跟Starter的設計理念相悖。在Starter的設計中,一般不推薦調(diào)用方手動進行額外的掃描。這是因為調(diào)用方引入了Starter,就應該依賴于 Starter提供的自動配置。手動掃描可能會導致不必要的麻煩,例如循環(huán)依賴、配置類的重復加載等問題。

假如我們現(xiàn)在沒有其他的配置了,比如說一下額外的屬性配置,那我們就可以打包與發(fā)布了。

打包與發(fā)布

此時我們就可以將自定義Starter打包,并發(fā)布到Maven倉庫或其他倉庫管理工具。

本地開發(fā)時,可以直接install。不必發(fā)不到私服。

測試

我們新建一個調(diào)用方的項目,在其中引入coderacademy-spring-boot-starter

<dependency>
    <groupId>com.springboot.coderacaemy</groupId>
    <artifactId>coderacermy-spring-boot-starter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

我們編寫測試類:

@SpringBootTest  
class SpringbootCodeApplicationTests {
    private CoderAcademyService coderAcademyService;

     @Test
    public void testCoderAcademy(){
       String str = coderAcademyService.sayHello();
       System.out.println(str);
    }

    @Autowired
    public void setCoderAcademyService(CoderAcademyService coderAcademyService) {
        this.coderAcademyService = coderAcademyService;
    }
}

執(zhí)行結果如下:

這樣一個很簡單的Starter就完成了。
當然在實際開發(fā)中,我們還需要一些自定義配置項需要注入到Starter中,才可以提供完整的服務。

配置屬性

我們新建一個CoderAcademyProperties類用于接收,調(diào)用方在自己項目中的application.yaml或者其他的配置中心配置的信息。

@ConfigurationProperties(prefix = "coderacademy")
public class CoderAcademyProperties {

    private String name = "碼農(nóng)Academy";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@ConfigurationProperties 是 SpringBoot中用于綁定外部配置到Bean的屬性上,prefix屬性指定了配置前綴。這樣我們就可以在調(diào)用方的application.yml中配置以coderacademy為前綴的信息。這里我們也給了默認值。

然后我們將這個配置注入到CoderAcademyService中去。

public class CoderAcademyService {

    private final CoderAcademyProperties coderAcademyProperties;

    public String sayHello(){
        return "Hello "+ coderAcademyConfig.getName();
    }

    public CoderAcademyService(CoderAcademyProperties coderAcademyProperties) {
        this.coderAcademyProperties = coderAcademyProperties;
    }
}

我們改動一下CoderAcademyService的AutoConfig。

@EnableConfigurationProperties({CoderAcademyProperties.class})
@Configuration
public class CoderAcademyAutoConfig {

    @Bean
    public CoderAcademyService coderAcademyService(CoderAcademyProperties coderAcademyProperties){
        return new CoderAcademyService(coderAcademyProperties);
    }
}

我重新Deploy之后,然后在調(diào)用方配置一下CoderAcademyProperties中對應的屬性:

coderacademy.name = CoderAcademy

再次跑一下單測:

在實際開發(fā)場景中,我們有時會遇到這樣的需求:調(diào)用方希望根據(jù)自身項目的需求靈活定義配置項,無需嚴格遵循CoderAcademyProperties中預設的模式(例如coderacademy.name)。例如,他們可能傾向于通過自定義屬性customer.starter.name來代替,并將這個屬性值映射到其項目的配置文件中。隨后,在調(diào)用方自己的@Configuration類里,基于這些個性化配置來創(chuàng)建一個CoderAcademyService實例。

然而,問題在于,Starter模塊內(nèi)部預先提供了一個默認的CoderAcademyService Bean定義。當調(diào)用方在其應用上下文中也聲明了同類型的Bean時,這將觸發(fā)Spring容器中的Bean沖突和初始化異常。為了解決這個問題,我們在設計Starter時需要考慮到這一點,我們在自動配置類中利用@ConditionalOnMissingBean注解來確保僅在容器中尚無CoderAcademyService Bean時才進行創(chuàng)建操作。這樣就避免了重復注冊同一類型Bean導致的問題。

@EnableConfigurationProperties({CoderAcademyProperties.class})
@Configuration
@ConditionalOnMissingBean(CoderAcademyService.class)
public class CoderAcademyAutoConfig {

    @Bean
    public CoderAcademyService coderAcademyService(CoderAcademyProperties coderAcademyProperties){
        return new CoderAcademyService(coderAcademyProperties);
    }
}

然后我們在調(diào)用方設計一個配置類,用于創(chuàng)建一個CoderAcademyService。

@Configuration
public class CustomerConfig {

    @Value("${customer.coderacademy.name}")
    private String customerName;

    @Bean
    public CoderAcademyService coderAcademyService(){
        CoderAcademyProperties properties = new CoderAcademyProperties();
        properties.setName(customerName);
        return new CoderAcademyService(properties);
    }
}

在調(diào)用方的application.properties加上customer.coderacademy.name配置。

customer.coderacademy.name = customer,coderacademy

我們再次在調(diào)用方執(zhí)行:

屬性配置提示

我們在使用其他的官方Starter時在application.properties或者application.yml配置相關屬性時,IDEA會自動給出屬性的Key的提示,以及給出默認值。那么在自定義Starter中該如何實現(xiàn)這功能呢?其實這就需要用到了我們引入的spring-boot-configuration-processor依賴。

spring-boot-configuration-processor 是 Spring Boot 提供的一個注解處理器,用于處理 @ConfigurationProperties 注解,生成配置屬性的元數(shù)據(jù),以提供更好的 IDE 支持和配置文件提示。注解處理器會掃描項目中標注了@ConfigurationProperties 注解的類,然后生成包含有關這些配置屬性的詳細信息的 spring-configuration-metadata.json文件。該文件位于META-INF下。這個元數(shù)據(jù)文件包含了配置屬性的描述、類型、默認值等信息,以提供更好的代碼提示和文檔生成功能。元數(shù)據(jù)文件被 IDE(如 IDEA、Eclipse)使用,用于提供更強大的代碼提示和補全功能。開發(fā)者在編輯配置文件時可以看到配置屬性的描述、類型等信息,更容易正確地配置應用程序。

當然添加依賴之后,我們還需要添加Maven的插件(如果使用的是Maven)。

 <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                            <version>2.7.0</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

然后我們執(zhí)行mvn clean -U install -DskipTests命令后,就可以在target下的META-INF就可以看見這個元數(shù)據(jù)文件。

我們在重新打包之后,在調(diào)用方的application.properties中配置屬性信息時,可以看到效果:

配置文件默認值

在上述示例中,我們在CoderAcademyProperties代碼中顯示的給name賦值了一個默認值。這種方式實現(xiàn)也可以,但是不夠優(yōu)雅,我們換一種優(yōu)雅的方式去實現(xiàn)配置的默認值設置。我們該用設置一個存儲默認值的配置文件coderacademy-default.properties,從這個文件綁定配置的默認值。

我們在resources/META-INF下創(chuàng)建一個coderacademy-default.properties。

coderacademy.name = Default CoderAcademy

然后在CoderAcademyAutoConfig中使用@PropertySource將這這個默認文件中的配置加載綁定到Bean中即CoderAcademyProperties中。

@AutoConfigureAfter({CoderAcademyPropertiesAutoConfig.class})
@EnableConfigurationProperties({CoderAcademyProperties.class})
@Configuration
@ConditionalOnMissingBean(CoderAcademyService.class)
@PropertySource(name = "CoderAcademy Default Properties", value = "classpath:/META-INF/coderacademy-default.properties")
public class CoderAcademyAutoConfig {

    @Bean
    public CoderAcademyService coderAcademyService(CoderAcademyProperties coderAcademyProperties){
        return new CoderAcademyService(coderAcademyProperties);
    }

}

在SpringBoot應用中,通過application.propertiesapplication.yml設置的屬性具有較高的優(yōu)先級。如果使用@PropertySource加載的屬性與前者有沖突,則會被后者覆蓋。

我們在調(diào)用方直接使用Starter中創(chuàng)建的CoderAcademyService,看一下效果:

即此時使用的是coderacademy-default.properties中配置的默認值。
我們在調(diào)用方配置coderacademy.name的值

coderacademy.name = This is CoderAcademy

再次運行一下數(shù)據(jù)

至此一個自定義的Starter就完成了。

示例

  • 項目架構:

  • 依賴:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
    </parent>

    <groupId>com.springboot.coderacaemy</groupId>
    <artifactId>coderacermy-spring-boot-starter</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-starter</name>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                            <version>2.7.0</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • 服務配置信息
@ConfigurationProperties(prefix = "coderacademy")
public class CoderAcademyProperties {

    private String url;

    private Integer port;

    private String userName;

    private String password;

    // 省略get set方法
}

CoderAcademyProperties主要作用是為了綁定application.properites中配置信息。其默認的配置文件coderacademy-default.properties

coderacademy.url=https://www.coderacademy.online/  
coderacademy.port=8080  
coderacademy.user-name=CoderAcademy  
coderacademy.password=123456
  • 服務配置類
    新建一個CoderAcademyConfig用于創(chuàng)建CoderAcademyService服務。CoderAcademyProperties只作為服務的配置信息,主要參與綁定外部配置文件中的配置信息。
public class CoderAcademyConfig {

    private String url;

    private Integer port;

    private String userName;

    private String password;

    // 省略 get  set
}

在創(chuàng)建一個將CoderAcademyProperties的參數(shù)綁定到配置類CoderAcademyConfig的一個自動裝配類CoderAcademyPropertiesAutoConfig。

@Configuration
@EnableConfigurationProperties({CoderAcademyProperties.class})
@PropertySource(name = "CoderAcademy Default Properties", value = "classpath:/META-INF/coderacademy-default.properties")
public class CoderAcademyPropertiesAutoConfig {

    @Bean
    public CoderAcademyConfig coderAcademyConfig(CoderAcademyProperties coderAcademyProperties){
        CoderAcademyConfig coderAcademyConfig = new CoderAcademyConfig();
        coderAcademyConfig.setPort(coderAcademyProperties.getPort());
        coderAcademyConfig.setUrl(coderAcademyProperties.getUrl());
        coderAcademyConfig.setPassword(coderAcademyProperties.getPassword());
        coderAcademyConfig.setUserName(coderAcademyProperties.getUserName());
       return coderAcademyConfig;
    }
}
  • 服務類
    服務類中就是用CoderAcademyConfig創(chuàng)建。
public class CoderAcademyService {

    private final CoderAcademyConfig coderAcademyConfig;

    public String connectDB(){
        return "Connect to " + coderAcademyConfig.getUrl() + ":" + coderAcademyConfig.getPort() + " successfully!";
    }

    public CoderAcademyService(CoderAcademyConfig coderAcademyConfig) {
        this.coderAcademyConfig = coderAcademyConfig;
    }

}

創(chuàng)建一個服務自動裝配類。

@Configuration  
@AutoConfigureAfter({CoderAcademyPropertiesAutoConfig.class})  
@ConditionalOnBean({CoderAcademyConfig.class})
public class CoderAcademyAutoConfig {

    @Bean
    @ConditionalOnMissingBean
    public CoderAcademyService coderAcademyService(CoderAcademyConfig coderAcademyConfig){
        return new CoderAcademyService(coderAcademyConfig);
    }
}

然后在META-INF/spring.factories下中使用EnableAutoConfiguration指定自動配置類。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.springboot.starter.coderacademy.config.CoderAcademyAutoConfig,com.springboot.starter.coderacademy.config.CoderAcademyPropertiesAutoConfig

這時就可以把這個Starter打包推到私服,就可以使用了。

總結

自定義Spring Boot Starter的原理是在應用啟動時,SpringBoot掃描含有spring.factories的jar包,加載其中的org.springframework.boot.autoconfigure.EnableAutoConfiguration條目。引入自定義starter后,相應的自動配置類會被檢測并加載到Spring容器執(zhí)行。通過條件注解等機制,可根據(jù)用戶提供的配置信息或其他Bean的存在動態(tài)配置和初始化Bean,實現(xiàn)功能的自動化裝配。自定義starter體現(xiàn)了SpringBoot模塊化和可擴展性,簡化了依賴管理和配置,使開發(fā)者能迅速構建具有特定功能的應用。

以上就是詳解SpringBoot如何創(chuàng)建自定義Starter的詳細內(nèi)容,更多關于SpringBoot自定義Starter的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解Java線程池是如何重復利用空閑線程的

    詳解Java線程池是如何重復利用空閑線程的

    在Java開發(fā)中,經(jīng)常需要創(chuàng)建線程去執(zhí)行一些任務,實現(xiàn)起來也非常方便,此時,我們很自然會想到使用線程池來解決這個問題,文中給大家提到使用線程池的好處,對Java線程池空閑線程知識感興趣的朋友一起看看吧
    2021-06-06
  • SpringBoot獲取配置文件內(nèi)容的幾種方式總結

    SpringBoot獲取配置文件內(nèi)容的幾種方式總結

    大家都知道SpringBoot獲取配置文件的方法有很多,下面這篇文章主要給大家介紹了關于SpringBoot獲取配置文件內(nèi)容的幾種方式,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • Java字符串轉整數(shù)與拼接實戰(zhàn)指南

    Java字符串轉整數(shù)與拼接實戰(zhàn)指南

    本文總結了Java中字符串轉整數(shù)和字符串相加的核心知識點,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2026-02-02
  • MyBatis-plus報錯Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的解決方法

    MyBatis-plus報錯Property ‘sqlSessionFactory‘ or 

    這篇文章主要給大家介紹了MyBatis-plus 報錯 Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的兩種解決方法,如果遇到相同問題的朋友可以參考借鑒一下
    2023-12-12
  • Java發(fā)送郵件遇到的常見需求匯總

    Java發(fā)送郵件遇到的常見需求匯總

    這篇文章主要介紹了Java發(fā)送郵件遇到的常見需求匯總的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • 如何使用Java生成PDF文檔詳解

    如何使用Java生成PDF文檔詳解

    這篇文章主要給大家介紹了關于如何使用Java生成PDF文檔的相關資料,PDF是可移植文檔格式,是一種電子文件格式,具有許多其他電子文檔格式無法相比的優(yōu)點,需要的朋友可以參考下
    2023-07-07
  • 創(chuàng)建Java線程安全類的七種方法

    創(chuàng)建Java線程安全類的七種方法

    線程安全是指某個方法或某段代碼,在多線程中能夠正確的執(zhí)行,不會出現(xiàn)數(shù)據(jù)不一致或數(shù)據(jù)污染的情況,我們把這樣的程序稱之為線程安全的,反之則為非線程安全的,下面這篇文章主要給大家介紹了關于創(chuàng)建Java線程安全類的七種方法,需要的朋友可以參考下
    2022-06-06
  • Java的Spring框架中實現(xiàn)發(fā)送郵件功能的核心代碼示例

    Java的Spring框架中實現(xiàn)發(fā)送郵件功能的核心代碼示例

    這篇文章主要介紹了Java的Spring框架中實現(xiàn)發(fā)送郵件功能的核心代碼示例,包括發(fā)送帶附件的郵件功能的實現(xiàn),需要的朋友可以參考下
    2016-03-03
  • Java實現(xiàn)多線程文件下載的代碼示例

    Java實現(xiàn)多線程文件下載的代碼示例

    本篇文章主要介紹了Java實現(xiàn)多線程下載的代碼示例,Java多線程可以充分利用CPU的資源,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • SpringSecurity自定義登錄接口的實現(xiàn)

    SpringSecurity自定義登錄接口的實現(xiàn)

    本文介紹了使用Spring Security實現(xiàn)自定義登錄接口,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-01-01

最新評論

桃园市| 凤城市| 丹阳市| 怀化市| 读书| 睢宁县| 甘孜| 汝阳县| 察隅县| 工布江达县| 广德县| 阿瓦提县| 公主岭市| 城固县| 高阳县| 营口市| 启东市| 民和| 崇礼县| 陕西省| 阳山县| 老河口市| 溆浦县| 兰溪市| 松阳县| 浮梁县| 定安县| 义马市| 常德市| 延边| 临夏县| 西盟| 青神县| 宿州市| 平顶山市| 木兰县| 松滋市| 孟村| 门头沟区| 汝阳县| 竹北市|