[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

到今天我们已经许多服务概念元件都提出来了,相信各位开发者对注解基本设计风格已有见解,明天开始我们将提出微服务架构及效能改进原理设计,因为天数不多,所以编排较紧,再请各位开发者见谅。


<<:  【Day09】Blocking & Non-Blocking 的差异

>>:  如何衡量万事万物 (3) 厘清问题 & 量化不确定性

卡夫卡的藏书阁【Book26】- Kafka - KafkaJS Admin 3

“You are at once both the quiet and the confusion...

自我笔记 - django 系列 [API风格篇]

django API 编写 以目前流行的restfull API来说,django提供了一些便捷的处...

Day37 参加职训(机器学习与资料分析工程师培训班),ResNet, RNN

ResNet架构 from tensorflow.keras import Input, Model...

30.MYSQL 资料统整 总结

今天是最後一篇发文了,上面介绍了很多指令,但是这些并不是所有的,这边只是帮大家简单介绍一些,比较好懂...

Day 14:怎麽在 Angular 使用 Bootstrap?

由於在未来的专案有机会使用到 Bootstrap,所以就藉这个机会来介绍一下如何在 Angular ...