1. 程式人生 > >Spring 註解程式設計之模式註解

Spring 註解程式設計之模式註解

Spring 框架中有很多可用的註解,其中有一類註解稱模式註解(Stereotype Annotations),包括 @Component@Service,@Controller,@Repository 等。只要在相應的類上標註這些註解,就能成為 Spring 中元件(Bean)。

需要配置開啟自動掃描。如在 XML 中配置 ` 或使用註解 @ComponentScan。

從最終的效果上來看,@Component@Service,@Controller,@Repository 起到的作用完全一樣,那為何還需要多個不同的註解?

從官方 wiki 我們可以看到原因。

stereotype annotation

 is an annotation that is used to declare the role that a component plays within the application. For example, the @Repository annotation in the Spring Framework is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO).

不同的模式註解雖然功能相同,但是代表含義卻不同。

標註@Controller 註解,這類元件就可以表示為 WEB 控制層 ,處理各種 HTTP 互動。標註 @Service 可以表示為內部服務層 ,處理內部服務各種邏輯。而 @Repository 可以代表示為資料控制層,代表資料庫增刪改查動作。

這樣一來不同模式註解帶來了不同的含義,清晰將服務進行分層。

除了上面的作用,特定的模式註解,Spring 可能會在未來增加額外的功能語義。如現在 @Repository 註解,可以增加異常的自動轉換功能。

所以,對於分層服務最好使用各自特定語義的模式註解,如 WEB 層就使用 @Controller註解。

模式註解原理

在 Spring 中任何標註 @Component

的元件都可以成為掃描的候選物件。另外任何使用 @Component 標註的註解,如 @Service,當其標註元件時,也能被當做掃描的候選物件。。

@Component is a generic stereotype for any Spring-managed component. Any component annotated with @Component is a candidate for component scanning. Similarly, any component annotated with an annotation that is itself meta-annotated with @Component is also a candidate for component scanning. For example, @Service is meta-annotated with @Component.

如果想使自定義的註解也能如 @Service 註解功能一樣,只要在自定義註解上標註 @Component 就可以。

AnnotationMetadata

從上面文件看出只要在類上存在 @Component註解,即使存在於註解的註解上,Spring 都將能其成為候選元件。

註解上的註解 Spring 將其定義為元註解(meta-annotation),如 @Component標註在 @Service上,@Component 就被稱作為元註解。後面我們就將註解的註解稱為元註解。

meta-annotation is an annotation that is declared on another annotation. An annotation is therefore meta-annotated if it is annotated with another annotation. For example, any annotation that is declared to be documented is meta-annotated with @Documented from thejava.lang.annotation package.

那麼對於一個類是否可以成為 Spring 元件,需要判斷這個類是否包含 @Component 註解,或者類上元註解中是否包含 @Component

在 Spring 中可以通過 MetadataReader 獲取 ClassMetadata 以及 AnnotationMetadata,然後獲取相應元資料。

ClassMetadata 可以獲取類的各種元資料,比如類名,介面等。

AnnotationMetadata 可以獲取當前類上註解的元資料,如註解名字,以及元註解資訊等。

所以只要獲取到 AnnotationMetadata,就可以判斷是否存在 @Component。判斷方式如下

獲取 AnnotationMetadata

這裡我們從 XML 配置開啟掃描開始講起。

<context:component-scan base-package="xxx.xxx.xx"/>

首先在 META-INF 下查詢 spring.handles 檔案。

不明白小夥伴們可以檢視上一篇文章 緣起 Dubbo ,講講 Spring XML Schema 擴充套件機制

context 標籤在 ContextNamespaceHandler 註冊 XML 解析器。在 ContextNamespaceHandler中其使用了 ComponentScanBeanDefinitionParser真正解析 XML。

ComponentScanBeanDefinitionParser#parse 方法中,首先獲取 XML 中配置 base-package屬性,獲取掃描的範圍,然後呼叫 ClassPathBeanDefinitionScanner#doScan 獲取 base-package 所有 BeanDefinition

doScan 方法中最終會呼叫ClassPathScanningCandidateComponentProvider#scanCandidateComponents 獲取掃描範圍內所有 BeanDefinition

scanCandidateComponents 中首先獲取掃描包範圍內資源物件,然後迭代從可讀取資源物件中MetadataReaderFactory#getMetadataReader(resource)獲取MetadataReader` 物件。

上文已經講到 MetadataReader 物件作用,這裡檢視如何使用MetadataReader 進行判斷。

篩選元件

isCandidateComponent方法中將會傳入 MetadataReaderTypeFilter#match進行判斷。

條件的判斷主要使用 excludeFiltersincludeFilters 兩個欄位決定。那兩個欄位從何處生成?

原來在ComponentScanBeanDefinitionParser中呼叫 ClassPathBeanDefinitionScanner構造方法時,預設傳入 useDefaultFilters=true

registerDefaultFilters 註冊預設的過濾器,生成 excludeFiltersincludeFilters 初始值。

預設情況下,excludeFilters 將會是個空集,而 includeFilters 集合中增加一個包含@Component 型別資訊的 AnnotationTypeFilter 例項,以及另外兩個包含 Java EE 註解AnnotationTypeFilter 例項。

跳到 AnnotationTypeFilter#match 方法中。AnnotationTypeFilter 類圖如下。

AnnotationTypeFilter#match 方法在抽象類 AbstractTypeHierarchyTraversingFilter中實現。

match 方法首先呼叫了 matchSelf,而該方法最終由 AnnotationTypeFilter 重寫。

可以看到這裡最終使用 AnnotationMetadata 方法判斷是否存在指定註解。

原始碼分析就到此為止,下篇文章將會深入 AnnotationMetadata,檢視其實如何獲取元資料的。

幫助文件

Spring Annotation Programming Model
beans-stereotype-annotations
『Spring Boot 程式設計思想』

相關推薦

Spring 註解程式設計模式註解

Spring 框架中有很多可用的註解,其中有一類註解稱模式註解(Stereotype Annotations),包括 @Component, @Service,@Controller,@Repository 等。只要在相應的類上標註這些註解,就能成為 Spring 中元件(Bean)。 需要配置開啟自動掃描

Spring 註解程式設計註解屬性別名與覆蓋

前兩篇文章咱聊了深入瞭解了 Spring 註解程式設計一些原理,這篇文章我們關注註解屬性方法,聊聊 Spring 為註解的帶來的功能,屬性別名與覆蓋。 註解屬性方法 在進入瞭解 Spring 註解屬性功能之前,我們先看一個正常 Java 註解。 在註解中,屬性方法與其他類/介面方法寫法類似,但是存在一些區

Spring 註解程式設計 AnnotationMetadata

在上篇文章 Spring 註解程式設計之模式註解 中我們講到 Spring 模式註解底層原理,依靠 AnnotationMetadata 介面判斷是否存在指定元註解。 這篇文章我們主要深入 AnnotationMetadata,瞭解其底層原理。 Spring 版本為 5.1.8-RELEASE Annot

Spring基礎知識基於註解的AOP

sdn 相互 com 目的 declare 裝配bean 四種 ace 裝配 背景概念:   1)橫切關註點:散布在應用中多處的功能稱為橫切關註點   2)通知(Advice):切面完成的工作。通知定了了切面是什麽及何時調用。     5中可以應用的通知:         

Spring】—AOPAspectJ註解方式實現聲明式事務管理

source xml配置 blog org 僅支持 選擇 imp 獨立 col 前言 這回來說下註解方式的聲明式事務管理。 正文 Demo 1、引入相關的jar包這裏寫圖片描述 2、引入AOP約束<beans xmlns:xsi="http://www.w3

Spring原始碼窺探註解方式的AOP原理

AOP入口程式碼分析 通過註解的方式來實現AOP1. @EnableAspectJAutoProxy通過@Import註解向容器中注入了AspectJAutoProxyRegistrar這個類,而它在容器中的名字是org.springframework.aop.config.internalAutoP

Spring定時任務@Scheduled註解(cron表示式詳解)

一個cron表示式有至少6個(也可能7個)有空格分隔的時間元素。       按順序依次為      1  秒(0~59)      2  分鐘(0~59)      3 小時(0~23)      4  天(0~31)      5 月(0~11)      6  星期

spring自動裝配@Qualifier註解的使用

當存在兩個型別一致的bean時,將會有什麼情況出現。我們一起來看看下面的例子:例子說明:如果已經看了上一篇教程,可以直接跳到第二步第一步:建立beanCustomer類package com.main.autowrite.autowired.annotation; imp

註解學習利用註解查詢控制元件

轉自:http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html 學習註解之前首先要理解元註解,元註解是用來註解自定義註解的註解 Java5.0定義了4個標準的meta-annotation型別,它們被用來提供對其它 annotation

Java程式設計師從笨鳥到菜鳥(七十二)細談Spring(四)利用註解實現spring基本配置詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Spring Boot annotation註解

頁面 osi 數據 加載 依賴註入 bsp 類型 數據庫 聲明 一:基於類的註解:(1)初始裝載@SpringBootApplication spring-boot程序入口標誌類@Configuration

Spring框架第四篇基於註解的DI註入

聯合 junit4 style troy ont student stc 創建配置文件 int 一、說明 [email protected]/* */,但意義不同的註解還有三個: 1)@Repository:註解在Dao實現類上 2)@Service:註解

spring AOP解析註解方式詳解

parser 分享 pro asp mes aop log space spec 命名空間處理器是AopNamespaceHandler,我們可以看到這裏註冊了幾個解析器,第一個我們知道是xml形式的解析,接下來我們看AspectJAutoProxyBeanDefiniti

spring boot框架學習學前掌握重要註解(1)-java配置方式

spring boot   本節主要內容:  1:重點註解介紹  2:使用重點註解環境搭建  聲明:  本文是《凱哥陪你學系列-框架學習之spring boot框架學習》中學前掌握之重要註解(1)  java配置是spring 4.x推薦的撇嘴方式。可以完全代替xml配置。  1:重點註解  @con

spring boot框架學習重要註解3註解方式讀取外部資源配置文件

凱哥java java註解 本節主要內容:1:是用非註解方式怎麽獲取配置文件中的配置項2:使用註解實戰獲取外部properties文件配置項聲明:本文是《凱哥陪你學系列-框架學習之spring boot框架學習》中spring boot框架學習學前掌握之重要註解(3)-通過註解方式讀取外部資源配置文件

spring boot框架學習學前掌握重要註解(4)-通過註解方式讀取外部資源配置文件2

spring boot kaigejava 凱哥java本節主要內容:1:思考問題:怎麽讀取多個配置文件,如果文件不存在怎麽辦2:配置數據庫連接池聲明:本文是《凱哥陪你學系列-框架學習之spring boot框架學習》中spring boot框架學習學前掌握之重要註解(4)-通過註解方式讀取外部資源配置文件2

spring boot框架學習學前掌握重要註解(2)-通過java的配置方式進行配置spring

凱哥java kaigejava本節主要內容:1:通過代碼演示實現零XML配置spring2:使用重點註解理解聲明:本文是《凱哥陪你學系列-框架學習之spring boot框架學習》中spring boot框架學習學前掌握之重要註解(2)-通過java的配置方式進行配置spring.在上一節《spring b

Spring框架 @Valid註解的使用(嵌套類型的效驗)

Springboot 之@Valid註解@Valid註解可以實現數據的驗證,你可以定義實體,在實體的屬性上添加校驗規則,而在API接收數據時添加@valid關鍵字,這時你的實體將會開啟一個校驗的功能。@Valid 註解類型的使用:@Null限制只能為null@NotNull限制必須不為null@AssertF

Spring(七)基於註解配置

關於 int ESS schema 控制 div except strong ont 基於註解的配置 從 Spring 2.5 開始就可以使用註解來配置依賴註入。而不是采用 XML 來描述一個 bean 連線,你可以使用相關類,方法或字段聲明的註解,將 bean 配置移動到

Spring Boot2.0註解方式啟動Springmvc

sch 一個tomcat user use embed spring serve XML java代碼 回顧下springmvc原理圖: DispatcherServlet是Spring MVC的核心,每當應用接受一個HTTP請求,由DispatcherServl