溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

發(fā)布時間:2022-08-16 10:48:48 來源:億速云 閱讀:182 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“SpringBoot SPI機制和自定義starter怎么實現(xiàn)”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“SpringBoot SPI機制和自定義starter怎么實現(xiàn)”吧!

    一、SpringBoot 中的SPI機制

    什么是spi呢,全稱是Service Provider Interface。簡單翻譯的話,就是服務提供者接口,是一種尋找服務實現(xiàn)的機制。

    其實就是一個規(guī)范定義、或者說是實現(xiàn)的標準。

    用生活中的例子說就是,你買了一臺小米的手機。

    但是你用的充電器并不一定非要是小米充電器,你可以拿其他廠商的充電器來進行充電,只要滿足協(xié)議、端口等要求,那么就是可以充電的。這也是一種熱拔插的思想,并不是固定死的。

    換成代碼來說也是一樣的,我定義了一個接口,但是不想固定死具體的實現(xiàn)類,因為那樣如果要更換實現(xiàn)類就要改動源代碼,這往往是不合適的。

    那么我也可以定義一個規(guī)范,在之后需要更換實現(xiàn)類或增加其他實現(xiàn)類時,遵守這個規(guī)范,我也可以動態(tài)的去發(fā)現(xiàn)這些實現(xiàn)類。

    換在SpringBoot中,就是現(xiàn)在的SpringBoot這個平臺定義了一些規(guī)范和標準,我現(xiàn)在想要讓SpringBoot平臺接納我。

    我該如何做呢?

    很簡單,按照它的標準和規(guī)范做事。

    SpringBoot在啟動的時候,會掃描所有jar包resource/META-INF/spring.factories文件,依據(jù)類的全限定名,利用反射機制將Bean裝載進容器中。

    二、自定義 starter

    說一說我的小實踐:

    在這個 starter 中,實現(xiàn)

    • 發(fā)送短線的Template

    • 對象存儲的Template

    的自動裝配~

    大致就是四步:

    • 用于映射配置文件中的配置的類xxxxProperties

    • 用于操作xxxx的接口和客戶端等等,如本文中的OssTemplate

    • 自動配置類xxxxAutoConfiguration ,并且向容器中注入xxxxTemplate

    • 在spring.factories中將xxxxAutoConfiguration添加進EnableAutoConfiguration的vaule集合中

    對象存儲我用的是阿里云的oss,里面的配置都是可以用的, 短信的話,就是個模擬的啦~,勿怪啦

    SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

    2.1、準備一個Maven項目

    刪除src目錄,

    然后再創(chuàng)建兩個 Maven項目(我個人習慣,習慣創(chuàng)建空Maven項目,實際上創(chuàng)建SpringBoot項目也是一樣)

    SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

    最外層的pom.xml

     <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>2.5.2</version>
         <relativePath/>
     </parent>
    
     <properties>
         <maven.compiler.source>8</maven.compiler.source>
         <maven.compiler.target>8</maven.compiler.target>
     </properties>
    
    
     <dependencies>
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-configuration-processor</artifactId>
             <optional>true</optional>
         </dependency>
     </dependencies>

    2.2、準備Properties類

    就是用來映射配置文件的~

     /**
      * @author Ning Zaichun
      */
     @Data
     @ConfigurationProperties(prefix = "nzc.oss")
     public class OssProperties {
    
         private String accessKey; 
         private String secret;
         private String bucketName;
         private String url;
         private String endpoint;
     }
     @Data
     @ConfigurationProperties(prefix = "nzc.sms")
     public class SmsProperties {
    
         private String name;
     }

    2.3、準備要注入的類

    就是我們最后要通過自動裝配注入進SpringBoot操作的類

    我這里分別是OssTemplate 和 SmsTemplate

     /**
      * @author Ning Zaichun
      */
     public class OssTemplate {
    
         private OssProperties ossProperties;
    
         public OssTemplate(OssProperties ossProperties) {
             this.ossProperties = ossProperties;
         }
    
         public String test() {
             System.out.println(ossProperties.getBucketName());
             return "test";
         }
         public String upload(String filename, InputStream is) {
             // yourEndpoint填寫B(tài)ucket所在地域?qū)腅ndpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
             String endpoint = ossProperties.getEndpoint();
             // 阿里云主賬號AccessKey擁有所有API的訪問權(quán)限,風險很高。強烈建議您創(chuàng)建并使用RAM賬號進行API訪問或日常運維,請登錄 https://ram.console.aliyun.com 創(chuàng)建RAM賬號。
             String accessKeyId = ossProperties.getAccessKey();
             String accessKeySecret = ossProperties.getSecret();
    
             // 創(chuàng)建OSSClient實例。
             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
             String storePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date()) + "/" + UUID.randomUUID() + filename.substring(filename.lastIndexOf("."));
    
             System.out.println(storePath);
             // 依次填寫B(tài)ucket名稱(例如examplebucket)和Object完整路徑(例如exampledir/exampleobject.txt)。Object完整路徑中不能包含Bucket名稱。
             ossClient.putObject(ossProperties.getBucketName(), storePath, is);
    
             String url = ossProperties.getUrl() + storePath;
    
             // 關(guān)閉OSSClient。
             ossClient.shutdown();
             return url + "#" + storePath;
        }
    
         public void remove(String fileUrl) {
             // yourEndpoint填寫B(tài)ucket所在地域?qū)腅ndpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
             String endpoint = ossProperties.getEndpoint();
             // 阿里云賬號AccessKey擁有所有API的訪問權(quán)限,風險很高。強烈建議您創(chuàng)建并使用RAM用戶進行API訪問或日常運維,請登錄RAM控制臺創(chuàng)建RAM用戶。
             String accessKeyId = ossProperties.getAccessKey();
             String accessKeySecret = ossProperties.getSecret();
             // 填寫B(tài)ucket名稱。
             String bucketName = ossProperties.getBucketName();
             // 填寫文件完整路徑。文件完整路徑中不能包含Bucket名稱。
             //2022/01/21/f0870eb3-4714-4fae-9fc3-35e72202f193.jpg
             String objectName = fileUrl;
    
             // 創(chuàng)建OSSClient實例。
             OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
             // 刪除文件或目錄。如果要刪除目錄,目錄必須為空。
             ossClient.deleteObject(bucketName, objectName);
    
             // 關(guān)閉OSSClient。
             ossClient.shutdown();
         }
     }
     public class SmsTemplate {
    
         private SmsProperties properties;
    
         public SmsTemplate(SmsProperties properties) {
             this.properties = properties;
         }
    
         public void sendSms(String mobile, String code){
             System.out.println(properties.getName()+"=="+mobile+"===="+code);
         }
     }

    2.4、AutoConfiguration

     @EnableConfigurationProperties({
         SmsProperties.class,
         OssProperties.class
             })
     public class CommonAutoConfig {
    
         @Bean
         public SmsTemplate smsTemplate(SmsProperties smsProperties){
             return new SmsTemplate(smsProperties);
         }
    
         @Bean
         public OssTemplate ossTemplate(OssProperties ossProperties){
             return new OssTemplate(ossProperties);
         }
    
     }

    2.5、編寫spring.factories

    在resource目錄下,創(chuàng)建一個META-INF文件夾,

    在META-INF文件夾下創(chuàng)建一個spring.factories文件

    內(nèi)容是

     org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
       com.nzc.CommonAutoConfig

    如果有多個就是:

     org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
       com.nzc.CommonAutoConfig \
       com.xxx.xxx

    SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

    到這一步之后,我們將這個項目,達成Jar包,然后在要使用的項目中進行引入。

    SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

    2.6、應用測試

    • 1、創(chuàng)建一個SpringBoot 的啟動類,有啟動類才能進行測試,不然沒上下文環(huán)境~

    • 2、編寫配置文件

     spring:
       application:
         name: app-server
     nzc:
       sms:
         name: ningzaichun
       oss:
         accessKey: xxx
         secret: xxx
         endpoint: oss-cn-shenzhen.aliyuncs.com
         bucketName: xxx
         url: xxx

    將oss的配置修改正確是可以用的~

    編寫測試類:

     @RunWith(SpringRunner.class)
     @SpringBootTest(classes = AppServerApplication.class)
     public class TemplateTest {
    
         @Autowired
         private OssTemplate ossTemplate;
         @Test
         public void testOss(){
             String s = ossTemplate.test();
             System.out.println(s);
         }
         @Test
         public void testUpload(){
             try {
                 File file = new File("D:\evectionflow01.png");
                 InputStream inputStream = new FileInputStream(file);
                 ossTemplate.upload("123.jpg",inputStream);
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             }
         }
         @Autowired
         private SmsTemplate smsTemplate;
    
         @Test
         public void testSendSms(){
             smsTemplate.sendSms("17670090715","123456");
         }
     }

    證明是可以使用的~

    SpringBoot?SPI機制和自定義starter怎么實現(xiàn)

    感謝各位的閱讀,以上就是“SpringBoot SPI機制和自定義starter怎么實現(xiàn)”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對SpringBoot SPI機制和自定義starter怎么實現(xiàn)這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI