iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0
Software Development

Wow ! There is no doubt about Learn Spring framework in a month.系列 第 9

[Day - 09] - Spring 模式註解之服務原理與開發

Abstract

前述章節以敘述過Spring Component註解的原理與運用,Spring核心所提供的幾項內建模式註解元件類別大多擴展於Component元件,通過此元件也可自定義所需的模式註解,便於各位開發者定義各類註解模式,以便劃分各種服務類別,以達到近十年來的主要領域驅動設計(DDD,Domain-Driven Design),此設計模式也是為目前流行的為服務架構的理論基礎,眾多服務要如何達到此理念的核心目的?主要需劃分各類服務類型元件,將各種服務細分化,再依照各種群組進行整合,所以可看出所有元件的核心來源註解稱之元件(@Component),透過擴展個元件去分類各種元件類型為服務類型(@Service)、倉儲庫事務交易類型(@Repository)或控制器類型(@Controller)等等,並在整合成一個大型服務稱之為一套系統,故開發者細分化這些元件類行為相當重要。

Principle Introduction

Spring核心所提供的幾項註解是可提供合併整合運用,並採用樹狀連結擴展方式將相關Spring的模式元件進行註冊,其拓展目標為透過元註解(@Component)進行擴展搜尋註冊,首當其衝的是,開發者須注意多重實作問題,無論何種註解在遇到此情況,皆會發生找不到相關的元件注入衝突,此時必須配置Bean名稱或配置權限(@Primary),不然預設都會是以類別名稱配置做為暫存在IoC配置池中索引名稱,即會造成尋找不到您的多重實作類別,我們將以下方程式碼做詳敘介紹。

  1. 定義Spring內部提供之服務模式註解(@Service)

1.1 配置介面,以便進行繼承多重實作

public interface NoteBookSellerService {
    List<NoteBook> getAllNoteBookList();
    NoteBook getNoteBookById(String id);
    List<NoteBook> updateNoteBookById(NoteBook noteBook);
    List<NoteBook> createNoteBookById(NoteBook noteBook);
}

1.2 進行繼承該介面,並配置服務模式註解及優先權,通過測試後,可發現到無需配置相關候選名稱即可自動注入首要服務模式元件。

@Primary
@Service
public class NoteBookSellerServiceImpl implements NoteBookSellerService {
    static List<NoteBook> noteBookList = new ArrayList<NoteBook>();

    static {
        noteBookList =  new ArrayList<NoteBook>(Arrays.asList(
                new NoteBook("1","A8460","ASUS","Release on future by Asus ! "),
                new NoteBook("2","MGOLD8888","APPLE","Release on future by Apple ! "),
                new NoteBook("3","HI9999","ACER","Release on future by Acer ! ")
        ));
    }
    @Override
    public List<NoteBook> getAllNoteBookList() {
        return noteBookList;
    }
    ...
    ...
    ...
}

    @Autowired
    NoteBookSellerService noteBookSellerService;
    
    @Test
    public void testGetAllNoteBookList() {
        ...
        List<NoteBook> noteBookList = noteBookSellerService.getAllNoteBookList();
        assertEquals(noteBookList.size() ,3);
        ...
        ...
    }

  1. 運用配置開發者所需的新模式註解,促使Spring 核心自動搜索到此關聯模式註解,並將此元件自動註冊入IoC配置池中,以便進行後續的服務注入行為。

2.1 我們這邊建構一個新服務類型稱之UniversalService,並以擴展原始服務模式註解(@Service)進行設計。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface UniversalService {

    @AliasFor(annotation = Service.class)
    String value() default "";
}

2.2 將此註解配置於新實作上,已達一種介面多種實作不同註解,並透過不同的BeanName進行注入,可看出最初的實作元件(NoteBookSellerServiceImpl)僅有定義服務註解(@Service)及優先權(Primary),如何達到不衝突,亦可自動注入,即在第二個實作配置候選元件名稱,或所有元件都配置名稱方式,即可達到需求。

@UniversalService("SecondHandSeller")
public class SecondHandSellerImpl implements NoteBookSellerService {
    static List<NoteBook> noteBookList = new ArrayList<NoteBook>();

    static {
        noteBookList =  new ArrayList<NoteBook>(Arrays.asList(
                new NoteBook("1","ZenBook 14 UX425EA","ASUS","Release version on 2021 ! "),
                new NoteBook("2","M1X MacBook Pro","APPLE","Release version on 2021 ! "),
                new NoteBook("3","SF514-55TA","ACER","Release version on 2021 ! ")
        ));
    }
    @Override
    public List<NoteBook> getAllNoteBookList() {
        return noteBookList;
    }
  .....
  .....
  .....
 }

2.3 透過測試進行判斷各種類型資料,即可確認我們已達到多種註解擴展分類與實作之目的。

public class NoteBookTestSuite extends ServiceTestBase {


    @Qualifier("SecondHandSeller")
    @Autowired
    NoteBookSellerService secondSellerService;

    @Test
    public void testGetAllNoteBookListBySecondhand() {

        List<NoteBook> noteBookList = secondSellerService.getAllNoteBookList();
        .....
        assertEquals(noteBookList.size() ,3);
        .....
    }
    
}

透過上方各項實作,開發者可再透過各種註解去分辨你的服務類型,以便達到更佳的專案管理效用。

Structure

先前我們已說元註解的架構,所有的模式註解皆擴展(extends)於元註解(@Component),開發者可自行設計註解進行擴展元註解(@Component)或相關模式註解(@Service),但在分類模式註解時,需注意@Target及@Retention兩項註解都需與擴展的元註解一致,故我們可從架構圖上得知,無論何種註解要進行擴展繼承,且要沿用元註解(@Service)的各項欄位,此時可透過@AliasFor(亦同類別super方法)傳遞參數,當系統啟動並觸發Spring核心內部啟動掃描註解(@Annotation)時,將以樹狀結構進行掃描後,在自動註冊於IoC配置池中,開發者亦可透過BeanFactory直接獲取所有已註冊之元件類別。

image
圖一 @Service註解架構圖

Follow up

Run test task

gradle test

Run open result html

open ./build/reports/tests/test/index.html

Test Report

Customer service annotation test
image

Mind-blowing test detail
image

Sample Source

Spring-Service-Sample

Reference Url

Where Should the Spring @Service Annotation Be Kept?

4.12 Classpath scanning, managed components and writing configurations using Java

Spring @Service註解應放置在哪裡?

Conclusion

到今天我們已經許多服務概念元件都提出來了,相信各位開發者對註解基本設計風格已有見解,明天開始我們將提出微服務架構及效能改進原理設計,因為天數不多,所以編排較緊,再請各位開發者見諒。


上一篇
[Day - 08] - Spring 通用注入各式元件運作與設計
下一篇
[Day - 10] - 運用FlywayDB自動化整合Spring JPA 的模式註解之旅
系列文
Wow ! There is no doubt about Learn Spring framework in a month.30

尚未有邦友留言

立即登入留言