前述章节以叙述过Spring Component注解的原理与运用,Spring核心所提供的几项内建模式注解元件类别大多扩展於Component元件,通过此元件也可自定义所需的模式注解,便於各位开发者定义各类注解模式,以便划分各种服务类别,以达到近十年来的主要领域驱动设计(DDD,Domain-Driven Design),此设计模式也是为目前流行的为服务架构的理论基础,众多服务要如何达到此理念的核心目的?主要需划分各类服务类型元件,将各种服务细分化,再依照各种群组进行整合,所以可看出所有元件的核心来源注解称之元件(@Component),透过扩展个元件去分类各种元件类型为服务类型(@Service)、仓储库事务交易类型(@Repository)或控制器类型(@Controller)等等,并在整合成一个大型服务称之为一套系统,故开发者细分化这些元件类行为相当重要。
Spring核心所提供的几项注解是可提供合并整合运用,并采用树状连结扩展方式将相关Spring的模式元件进行注册,其拓展目标为透过元注解(@Component)进行扩展搜寻注册,首当其冲的是,开发者须注意多重实作问题,无论何种注解在遇到此情况,皆会发生找不到相关的元件注入冲突,此时必须配置Bean名称或配置权限(@Primary),不然预设都会是以类别名称配置做为暂存在IoC配置池中索引名称,即会造成寻找不到您的多重实作类别,我们将以下方程序码做详叙介绍。
- 定义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);
...
...
}
- 运用配置开发者所需的新模式注解,促使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);
.....
}
}
透过上方各项实作,开发者可再透过各种注解去分辨你的服务类型,以便达到更佳的专案管理效用。
先前我们已说元注解的架构,所有的模式注解皆扩展(extends)於元注解(@Component),开发者可自行设计注解进行扩展元注解(@Component)或相关模式注解(@Service),但在分类模式注解时,需注意@Target及@Retention两项注解都需与扩展的元注解一致,故我们可从架构图上得知,无论何种注解要进行扩展继承,且要沿用元注解(@Service)的各项栏位,此时可透过@AliasFor(亦同类别super方法)传递参数,当系统启动并触发Spring核心内部启动扫描注解(@Annotation)时,将以树状结构进行扫描後,在自动注册於IoC配置池中,开发者亦可透过BeanFactory直接获取所有已注册之元件类别。
图一 @Service注解架构图
Run test task
gradle test
Run open result html
open ./build/reports/tests/test/index.html
Customer service annotation test
Mind-blowing test detail
Where Should the Spring @Service Annotation Be Kept?
4.12 Classpath scanning, managed components and writing configurations using Java
到今天我们已经许多服务概念元件都提出来了,相信各位开发者对注解基本设计风格已有见解,明天开始我们将提出微服务架构及效能改进原理设计,因为天数不多,所以编排较紧,再请各位开发者见谅。
<<: 【Day09】Blocking & Non-Blocking 的差异
>>: 如何衡量万事万物 (3) 厘清问题 & 量化不确定性
“You are at once both the quiet and the confusion...
django API 编写 以目前流行的restfull API来说,django提供了一些便捷的处...
ResNet架构 from tensorflow.keras import Input, Model...
今天是最後一篇发文了,上面介绍了很多指令,但是这些并不是所有的,这边只是帮大家简单介绍一些,比较好懂...
由於在未来的专案有机会使用到 Bootstrap,所以就藉这个机会来介绍一下如何在 Angular ...