Spring常用註解

BugWritt3r發表於2021-02-05

 

Spring常用註解

本文列舉一些常用的SpringBoot開發註解,希望能幫助讀者在SpringBoot開發中正確地使用註解。

@Spring Application

主程式註解,spring框架的main函式自帶註解。一般不需要開發人員操作,Spring Initializer會寫好。

@Controller

標註控制器類,控制器中的方法可以返回一個檢視,在Web開發中一般使用的少(主要是用@RestController)。

@ResponseBody

@Controller+@ResponseBody=@RestController

因為SpringBoot已經封裝了@RestController,所以一般不需要使用上面等式左邊的方式(好比茴字的四種寫法),我個人認為不需要花時間學習。

@RequestBody

@PostMapping中會再次介紹。將json解析為java物件。

使用場景:json傳參

@RequestMapping

@RequestMapping(“url“),用來將請求對映到方法。

在實際開發中,在具體的控制器類之前新增該註解即可。

@RequestParam

用來獲取url中?後的引數。

public void searchById(@RequestParam(value ="id", required true, defaultValue "0")int id){
// required, defaultValue不寫也可以
...
}

使用場景:URL傳參

@PathVariable

同樣是從URL中獲得引數,方式和@RequestParam不一樣。

@RequestMapping("/user/{id}")
public void searchById(@PathVariable(required true)int id){
...
}

使用場景:URL傳參

@RestController

作用=@Controller+@ResponseBody,返回json格式資料。現在Web開發中的Controller一般都是RestController。

一般和@RequestMapping、@GetMapping、@PostMapping配合使用。

使用方法:

@RequestController
public class RestController {
...
}

@GetMapping

響應GET請求。

@RequestController
@RequestMapping("rest")
public class RestController {
 @GetMapping("get") // http://localhost:8080/rest/get
 public String get(){
   return "";
}
}

@GetMapping可以使用@PathVariable、@RequestParam

@PostMapping

響應POST請求。

@RequestController
@RequestMapping("rest")
public class RestController {
 @PostMapping("post") // http://localhost:8080/rest/post
 public String post(@RequestBody User user){
   return "";
}
}

一般來說,POST方法的傳參不受限制,可以使用URL傳參,也可以使用@RequestBody獲取請求體中的json,並解析為響應的java物件。

POST方法和GET方法可以共用一個URL,不用擔心起衝突,即下面的使用方式是OK的:

@RequestController
@RequestMapping("rest")
public class RestController {
 @GetMapping
 public String get(){
   return "";
}
 @PostMapping
 public String post(@RequestBody User user){
   return user.toString();
}
}
// 不會衝突,只要請求方法正確(正確使用GET、POST),就能被正確的方法響應。

@PutMapping、@DeleteMapping使用方式大同小異,其實從功能上來說,@PostMapping能替代所有的請求,但是這麼使用會導致程式碼語義混亂

簡單說明一下各種請求方法的使用場景:

方法場景
GET 獲取資源
POST 新增資源
PUT 更新資源
DELETE 刪除資源

@CrossOrigin

用來解決跨域問題,何為跨域移步這裡

在Blog中,博主給了跨域的詳細例子:

當前頁面url被請求頁面url是否跨域原因
http://www.test.com/ http://www.test.com/index.html 同源(協議、域名、埠號相同)
http://www.test.com/ https://www.test.com/index.html 跨域 協議不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 埠號不同(8080/7001)

(上表來自連結博文)

關於AJAX跨域問題移步這裡

@RequestController
@RequestMapping("rest")
public class RestController {
 @PostMapping
 @CrossOrigin
 public String post(@RequestBody User user){
   return user.toString();
}
}
//跨域問題解決

@Service

Controller中一般是不寫邏輯的,都是直接呼叫相應的服務,我們需要吧業務邏輯封裝在服務中。

上面的例子只是為了方便才把邏輯寫入控制器,實際開發中不要圖這種方便。

@Service用來註冊bean,要放在服務的實現類之前。

接下來使用UserService做例子。這是一個介面。

// 介面類
public class UserService {
 public ResponseVO addUser(User user);
}
// 實現類

@Service // 一定是在實現類而非介面類中
public class UserServiceImpl implements UserService {
 
public ResponseVO addUser(User user){
   // implement the interface
}
}
// 控制器類
public class UserController {
 @Autowired
 private UserService userService;
}

一般在控制器類中,又一個Service成員,在這個例子中便是private UserService userService

我們當然可以選擇:

private UserService userService new UserServiceImpl();

但是SpringBoot提供了更方便的做法:

@Autowired
private UserService userService;

只要實現類被正確的標註,那麼@Autowired就能幫我們完成初始化任務。

關於Autowired的進一步介紹移步@Autowired

@Component

@Component和@Service非常類似,同樣用來註冊bean,使用方式也是一樣的,區別在二者的使用場景。

@Service用於註解業務邏輯層中的服務程式碼,@Component用於註解通用性強的工具類(會被多方呼叫)。

例如:

  1. 既被控制器呼叫,又被服務實現類呼叫的類

  2. 被多個控制器/服務實現類呼叫的類

@Autowired

@Autowired用來獲取bean。

在SpringBoot中,預設的匹配方式是byType,具體規則如下:

  1. 按照型別去容器找到對應的元件

    如果找到:賦值

    如果沒找到:報異常

    如果找到多個:使用變數名作ID匹配,匹配上就賦值,沒有就報錯。

    這裡說明一下:ID即為類名的首字母小寫,例如UserServiceImpl類的ID就是userServiceImpl

  2. 可以使用@Qualifier註解指定ID

例子:

  1. 使用變數名作ID匹配

@Autowired
private UserService userService;

查詢到多個相同的類:UserService(id = userService)及其子類UserServiceExtend(id = userServiceExtend)

這時,使用userService作id匹配到UserService類。

  1. 使用@Qualifier指定id

@Autowired
@Qualfier("adminServiceImpl")
private UserService userService; // private UserService userService = new AdminServiceImpl();
...

...
public class AdminServiceImpl implements UserService{
...
}
  1. required=false

    @Autowired是預設required=true的,設為false找不到就不會報錯,而是置為null。

@Resource

沒有@Autowired的按類匹配機制,但是可以指定name

@Resource(adminServiceImpl)
private UserService adminService;
...

public class AdminServiceImpl implements UserService{
...
}

功能基本被@Autowired覆蓋。

@Resource(name = id) = @Qualifier(id) + @Autowired

除了利用上面這個等式縮減程式碼,我想不到別的使用場景。

@Configuration + @Beans

這倆是一起使用的,可以人為註冊Bean,替代@Service和@Component

@Configuration
public class Beans{
 @Bean
 public UserService userServiceImpl(){
   return new UserServiceImpl();
}
 @Bean
 public UserService adminServiceImpl(){
   return new AdminServiceImpl();
}
}

// UserController.java
@Resource(name=adminServiceImpl)
private UserService adminService;

@Resource(name=userServiceImpl)
private UserService userService;

說實話比較雞肋的功能......反正瞭解就好。

@Value

還差一口氣就看完了。

@Value用來從配置檔案(.properties/.yaml/.yml)中取引數。

例如:

# application.properties

local.name = crx
@Value("${local.name}")
private String author;

一般只有一些賬戶密碼資料需要使用該功能。

 

常用註解到這裡就介紹完了,最後說一句,實操才是硬道理,要多練!

相關文章