Spring/SpringBoot 常用注解

在spring中有兩種注入方式一種是XML文件注入,另一種則是注解注入,注解短小精悍,使用注解就無需配置復雜的 xml文件了。而現(xiàn)如今為了節(jié)約開發(fā)的時間成本大多使用注解去開發(fā)。
注解
@SpringBootApplication
這個注解是 Spring Boot 項目的基石,創(chuàng)建 SpringBoot 項目之后會默認在主類加上。
這一個注解其實包含了三個注解的功能,我們都知道springboot是對spring框架的集成用于簡化開發(fā),那么為什么不直記錄Springboot的注解呢?因為有些時候我們需要用到第三方jar包時,第三方jar并沒有使用spring框架,為了方便管理,我們需要使用到spring的相關注解,將jar對象注入到IOC容器當中去管理。我們可以把?@SpringBootApplication
看作是?@Configuration
、@EnableAutoConfiguration
、@ComponentScan
?注解的集合。
根據(jù) SpringBoot 官網(wǎng),這三個注解的作用分別是:
@EnableAutoConfiguration
:啟用 SpringBoot 的自動配置機制@ComponentScan
: 掃描被@Component
?(@Service
,@Controller
)注解的 bean,注解默認會掃描該類所在的包下所有的類。@Configuration
:允許在 Spring 上下文中注冊額外的 bean 或導入其他配置類
Spring Bean 相關注解
1.1
@Autowired
自動導入對象到類中,被注入進的類同樣要被 Spring 容器管理比如:Service 類注入到 Controller 類中。
2.2. @Component
,@Repository
,@Service
,?@Controller
我們一般使用?@Autowired
?注解讓 Spring 容器幫我們自動裝配 bean。要想把類標識成可用于?@Autowired
?注解自動裝配的 bean 的類,可以采用以下注解實現(xiàn):
@Component
?:通用的注解,可標注任意類為?Spring
?組件。如果一個 Bean 不知道屬于哪個層,可以使用@Component
?注解標注。@Repository
?: 對應持久層即 Dao 層,主要用于數(shù)據(jù)庫相關操作。@Service
?: 對應服務層,主要涉及一些復雜的邏輯,需要用到 Dao 層。@Controller
?: 對應 Spring MVC 控制層,主要用戶接受用戶請求并調用 Service 層返回數(shù)據(jù)給前端頁面。
2.3.?@RestController
@RestController
注解是@Controller和
@ResponseBody
的合集,表示這是個控制器 bean,并且是將函數(shù)的返回值直 接填入 HTTP 響應體中,是 REST 風格的控制器。
Guide 哥:現(xiàn)在都是前后端分離,說實話我已經(jīng)很久沒有用過@Controller
。如果你的項目太老了的話,就當我沒說。
單獨使用?@Controller
?不加?@ResponseBody
的話一般使用在要返回一個視圖的情況,這種情況屬于比較傳統(tǒng)的 Spring MVC 的應用,對應于前后端不分離的情況。@Controller
?+@ResponseBody
?返回 JSON 或 XML 形式數(shù)據(jù)
2.4.?@Scope
聲明 Spring Bean 的作用域
四種常見的 Spring Bean 的作用域:
singleton : 唯一 bean 實例,Spring 中的 bean 默認都是單例的。
prototype : 每次請求都會創(chuàng)建一個新的 bean 實例。
request : 每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP request 內有效。
session : 每一次 HTTP 請求都會產生一個新的 bean,該 bean 僅在當前 HTTP session 內有效。
2.5. @Configuration
一般用來聲明配置類,可以使用?@Component
注解替代,不過使用Configuration
注解聲明配置類更加語義化。
3. 處理常見的 HTTP 請求類型
5 種常見的請求類型:
GET?:請求從服務器獲取特定資源。舉個例子:
GET /users
(獲取所有學生)POST?:在服務器上創(chuàng)建一個新的資源。舉個例子:
POST /users
(創(chuàng)建學生)PUT?:更新服務器上的資源(客戶端提供更新后的整個資源)。舉個例子:
PUT /users/12
(更新編號為 12 的學生)DELETE?:從服務器刪除特定的資源。舉個例子:
DELETE /users/12
(刪除編號為 12 的學生)PATCH?:更新服務器上的資源(客戶端提供更改的屬性,可以看做作是部分更新),使用的比較少,這里就不舉例子了。
3.1. GET 請求
@GetMapping("users")
?等價于@RequestMapping(value="/users",method=RequestMethod.GET)
3.2. POST 請求
@PostMapping("users")
?等價于@RequestMapping(value="/users",method=RequestMethod.POST)
3.3. PUT 請求
@PutMapping("/users/{userId}")
?等價于@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
3.4. DELETE 請求
@DeleteMapping("/users/{userId}")
等價于@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)
3.5. PATCH 請求
一般實際項目中,我們都是 PUT 不夠用了之后才用 PATCH 請求去更新數(shù)據(jù)。
4. 前后端傳值
掌握前后端傳值的正確姿勢,是你開始 CRUD 的第一步!
4.1.?@PathVariable
?和?@RequestParam
@PathVariable
用于獲取路徑參數(shù),@RequestParam
用于獲取查詢參數(shù)。
4.2.?@RequestBody
用于讀取 Request 請求(可能是 POST,PUT,DELETE,GET 請求)的 body 部分并且Content-Type 為 application/json?格式的數(shù)據(jù),接收到數(shù)據(jù)之后會自動將數(shù)據(jù)綁定到 Java 對象上去。系統(tǒng)會使用HttpMessageConverter
或者自定義的HttpMessageConverter
將請求的 body 中的 json 字符串轉換為 java 對象。
5. 讀取配置信息

下面我們來看一下 Spring 為我們提供了哪些方式幫助我們從配置文件中讀取這些配置信息。
@value
(常用)
使用?@Value("${property}")
其中property為application.yml配置文件中的字段
@ConfigurationProperties
(常用)
通過@ConfigurationProperties
讀取配置信息并與 bean 綁定。
你可以像使用普通的 Spring bean 一樣,將其注入到類中使用。

5.3.?PropertySource
(不常用)
@PropertySource
讀取指定 properties 文件

6. 參數(shù)校驗
數(shù)據(jù)的校驗的重要性就不用說了,即使在前端對數(shù)據(jù)進行校驗的情況下,我們還是要對傳入后端的數(shù)據(jù)再進行一遍校驗,避免用戶繞過瀏覽器直接通過一些 HTTP 工具直接向后端請求一些違法數(shù)據(jù)。
JSR(Java Specification Requests)?是一套 JavaBean 參數(shù)校驗的標準,它定義了很多常用的校驗注解,我們可以直接將這些注解加在我們 JavaBean 的屬性上面,這樣就可以在需要校驗的時候進行校驗了,非常方便!
校驗的時候我們實際用的是?Hibernate Validator?框架。Hibernate Validator 是 Hibernate 團隊最初的數(shù)據(jù)校驗框架,Hibernate Validator 4.x 是 Bean Validation 1.0(JSR 303)的參考實現(xiàn),Hibernate Validator 5.x 是 Bean Validation 1.1(JSR 349)的參考實現(xiàn),目前最新版的 Hibernate Validator 6.x 是 Bean Validation 2.0(JSR 380)的參考實現(xiàn)。
SpringBoot 項目的 spring-boot-starter-web 依賴中已經(jīng)有 hibernate-validator 包,不需要引用相關依賴。如下圖所示(通過 idea 插件—Maven Helper 生成):
?所有的注解,推薦使用 JSR 注解,即javax.validation.constraints
,而不是org.hibernate.validator.constraints
6.1. 一些常用的字段驗證的注解
@NotEmpty 被注釋的字符串的不能為 null 也不能為空
@NotBlank 被注釋的字符串非 null,并且必須包含一個非空白字符
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Pattern(regex=,flag=)被注釋的元素必須符合指定的正則表達式
@Email 被注釋的元素必須是 Email 格式。
@Min(value)被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值
@Max(value)被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值
@DecimalMin(value)被注釋的元素必須是一個數(shù)字,其值必須大于等于指定的最小值
@DecimalMax(value) 被注釋的元素必須是一個數(shù)字,其值必須小于等于指定的最大值
@Size(max=, min=)被注釋的元素的大小必須在指定的范圍內
@Digits(integer, fraction)被注釋的元素必須是一個數(shù)字,其值必須在可接受的范圍內
@Past被注釋的元素必須是一個過去的日期
@Future 被注釋的元素必須是一個將來的日期
…
6.2. 驗證請求體(RequestBody)
我們在需要驗證的參數(shù)上加上了@Valid
注解,如果驗證失敗,它將拋出MethodArgumentNotValidException
。
6.3. 驗證請求參數(shù)(Path Variables 和 Request Parameters)
一定一定不要忘記在類上加上?@Validated
?注解了,這個參數(shù)可以告訴 Spring 去校驗方法參數(shù)。
7. 全局處理 Controller 層異常
介紹一下我們 Spring 項目必備的全局處理 Controller 層異常。
相關注解:
@ControllerAdvice :注解定義全局異常處理類
@ExceptionHandler :注解聲明異常處理方法
如何使用呢?拿我們在第 5 節(jié)參數(shù)校驗這塊來舉例子。如果方法參數(shù)不對的話就會拋出MethodArgumentNotValidException,我們來處理這個異常。
8. JPA 相關
8.1. 創(chuàng)建表
@Entity
聲明一個類對應一個數(shù)據(jù)庫實體。
@Table
?設置表名
8.2. 創(chuàng)建主鍵
@Id
?:聲明一個字段為主鍵。
使用@Id
聲明之后,我們還需要定義主鍵的生成策略。我們可以使用?@GeneratedValue
?指定主鍵生成策略。
1.通過?@GeneratedValue
直接使用 JPA 內置提供的四種主鍵生成策略來指定主鍵生成策略。
JPA 使用枚舉定義了 4 種常見的主鍵生成策略,如下:
一般使用 MySQL 數(shù)據(jù)庫的話,使用GenerationType.IDENTITY
策略比較普遍一點(分布式系統(tǒng)的話需要另外考慮使用分布式 ID)。
2.通過?@GenericGenerator
聲明一個主鍵策略,然后?@GeneratedValue
使用這個策略
等價于:
8.3. 設置字段類型
@Column
?聲明字段。
示例:
設置屬性 userName 對應的數(shù)據(jù)庫字段名為 user_name,長度為 32,非空
設置字段類型并且加默認值,這個還是挺常用的。
8.4. 指定不持久化特定字段
@Transient
?:聲明不需要與數(shù)據(jù)庫映射的字段,在保存的時候不需要保存進數(shù)據(jù)庫 。
如果我們想讓secrect
?這個字段不被持久化,可以使用?@Transient
關鍵字聲明。
了?@Transient
關鍵字聲明, 還可以采用下面幾種方法:
一般使用注解的方式比較多。
8.5. 聲明大字段
@Lob
:聲明某個字段為大字段。
更詳細的聲明:
8.6. 創(chuàng)建枚舉類型的字段
可以使用枚舉類型的字段,不過枚舉字段要用@Enumerated
注解修飾。
數(shù)據(jù)庫里面對應存儲的是 MALE/FEMALE。
8.7. 增加審計功能
只要繼承了?AbstractAuditBase
的類都會默認加上下面四個字段。
我們對應的審計功能對應地配置類可能是下面這樣的(Spring Security 項目):
簡單介紹一下上面涉及到的一些注解:
@CreatedDate: 表示該字段為創(chuàng)建時間字段,在這個實體被 insert 的時候,會設置值
@CreatedBy :表示該字段為創(chuàng)建人,在這個實體被 insert 的時候,會設置值
@LastModifiedDate、@LastModifiedBy同理。
@EnableJpaAuditing:開啟 JPA 審計功能。
8.8. 刪除/修改數(shù)據(jù)
@Modifying 注解提示 JPA 該操作是修改操作,注意還要配合@Transactional注解使用。
8.9. 關聯(lián)關系
@OneToOne 聲明一對一關系
@OneToMany 聲明一對多關系
@ManyToOne 聲明多對一關系
@MangToMang 聲明多對多關系
用 JPAopen in new window 。
9. 事務 @Transactional
在要開啟事務的方法上使用@Transactional注解即可!
我們知道 Exception 分為運行時異常 RuntimeException 和非運行時異常。在@Transactional注解中如果不配置rollbackFor屬性,那么事務只會在遇到RuntimeException的時候才會回滾,加上rollbackFor=Exception.class,可以讓事務在遇到非運行時異常時也回滾。
@Transactional 注解一般可以作用在類或者方法上。
作用于類:當把@Transactional 注解放在類上時,表示所有該類的 public 方法都配置相同的事務屬性信息。
作用于方法:當類配置了@Transactional,方法也配置了@Transactional,方法的事務會覆蓋類的事務配置信息。
更多關于 Spring 事務的內容請查看我的這篇文章:可能是最漂亮的 Spring 事務管理詳解 。
10. json 數(shù)據(jù)處理
10.1. 過濾 json 數(shù)據(jù)
@JsonIgnoreProperties 作用在類上用于過濾掉特定字段不返回或者不解析。
@JsonIgnore
一般用于類的屬性上,作用和上面的@JsonIgnoreProperties
?一樣。
10.2. 格式化 json 數(shù)據(jù)
@JsonFormat
一般用來格式化 json 數(shù)據(jù)。
比如:
10.3. 扁平化對象
未扁平化之前:
使用@JsonUnwrapped
?扁平對象之后:
11. 測試相關
@ActiveProfiles
一般作用于測試類上, 用于聲明生效的 Spring 配置文件。
@Test
聲明一個方法為測試方法
@Transactional
被聲明的測試方法的數(shù)據(jù)會回滾,避免污染測試數(shù)據(jù)。
@WithMockUser
?Spring Security 提供的,用來模擬一個真實用戶,并且可以賦予權限。