最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot常見的一些相關(guān)注解總結(jié)

 更新時間:2025年10月31日 09:35:53   作者:把csdn當日記本的菜雞  
在springboot中,摒棄了spring以往項目中大量繁瑣的配置,遵循約定大于配置的原則,通過自身默認配置,極大的降低了項目搭建的復雜度,這篇文章主要介紹了springboot常見的一些相關(guān)注解,需要的朋友可以參考下

Spring 注解大全

本文檔詳細介紹了 Spring 框架中常用的核心注解,幫助開發(fā)者更好地理解和使用這些注解。Spring 注解極大地簡化了配置,提高了開發(fā)效率,是現(xiàn)代 Spring 應用開發(fā)的基礎。

1. @Controller

@Controller 是 Spring Framework 中用于標記Web 控制器的核心注解,屬于 Spring MVC 的核心組件。它用于定義一個類作為處理 HTTP 請求的入口點,負責接收請求、調(diào)用業(yè)務邏輯并返回視圖或數(shù)據(jù)。

核心作用

  • 請求映射:通過 @RequestMapping 或其派生注解(如 @GetMapping、@PostMapping)將 HTTP 請求映射到控制器的方法。
  • 視圖解析:返回字符串時,Spring 會使用視圖解析器(如 Thymeleaf、JSP)將其轉(zhuǎn)換為實際的視圖(如 HTML 頁面)。
  • 數(shù)據(jù)綁定:自動將請求參數(shù)、表單數(shù)據(jù)或路徑變量綁定到方法參數(shù)(結(jié)合 @RequestParam、@PathVariable 等注解)。

基礎用法示例

場景 1:返回視圖

@Controller
@RequestMapping("/users")
public class UserController {

    // 處理 GET /users/profile?name=John
    @GetMapping("/profile")
    public String getProfile(@RequestParam String name, Model model) {
        model.addAttribute("userName", name); // 將數(shù)據(jù)傳遞給視圖
        return "userProfile"; // 對應視圖解析器配置的模板(如 userProfile.html)
    }
}

場景 2:返回 JSON 數(shù)據(jù)(需配合 @ResponseBody)

@Controller
@RequestMapping("/api")
public class ApiController {

    // 返回 JSON 數(shù)據(jù)(需要手動添加 @ResponseBody)
    @GetMapping("/data")
    @ResponseBody
    public User getData() {
        return new User("Alice", 30); // 自動轉(zhuǎn)換為 JSON
    }
}

@Controller vs @RestController

  • @Controller

    • 傳統(tǒng) MVC 控制器,默認返回視圖名稱。若需返回 JSON/XML 等數(shù)據(jù),需在方法上添加 @ResponseBody。
  • @RestController

    • @Controller + @ResponseBody 的組合注解,所有方法默認返回數(shù)據(jù)而非視圖(自動序列化為 JSON/XML)。
@RestController
@RequestMapping("/api")
public class UserRestController {
    @GetMapping("/user")
    public User getUser() {
        return new User("Bob", 25); // 自動返回 JSON
    }
}

關(guān)鍵注解配合使用

注解作用示例
@RequestMapping類/方法級請求映射@RequestMapping(“/home”)
@GetMapping快捷注解(GET 請求)@GetMapping(“/list”)
@PostMapping快捷注解(POST 請求)@PostMapping(“/save”)
@PathVariable綁定 URI 模板變量@GetMapping(“/users/{id}”) public User getUser(@PathVariable Long id)
@RequestParam綁定請求參數(shù)@RequestParam String name
@RequestBody綁定請求體數(shù)據(jù)(JSON/XML)public void saveUser(@RequestBody User user)
@ModelAttribute綁定表單數(shù)據(jù)到對象public String handleForm(@ModelAttribute User user)

高級特性

視圖解析器配置

在 Spring Boot 中,默認集成 Thymeleaf 或 FreeMarker,通過 application.properties 配置:

spring.mvc.view.prefix=/WEB-INF/views/  # 視圖模板前綴
spring.mvc.view.suffix=.html           # 視圖模板后綴

會話管理

@SessionAttributes:在控制器類上聲明需要存儲到會話中的模型屬性。

@Controller
@SessionAttributes("user") // 將 "user" 屬性存儲到會話中
public class SessionController {
    @GetMapping("/set")
    public String setSession(Model model) {
        model.addAttribute("user", new User("Alice"));
        return "sessionPage";
    }
}

異常處理

@ExceptionHandler:在控制器內(nèi)處理局部異常。

@Controller
public class ErrorController {
    @ExceptionHandler(Exception.class)
    public String handleException() {
        return "errorPage"; // 異常時返回錯誤頁面
    }
}

最佳實踐

  • 明確職責分離

    • 控制器負責接收請求和調(diào)用服務層,業(yè)務邏輯應放在 Service 層。
    • 避免在控制器中編寫復雜邏輯。
  • 合理使用注解

    • RESTful API 優(yōu)先使用 @RestController。
    • 傳統(tǒng) Web 應用使用 @Controller + 視圖解析器。
  • 參數(shù)校驗

    • 結(jié)合 @Valid 和 BindingResult 進行請求參數(shù)校驗。
@PostMapping("/save")
public String saveUser(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "formPage"; // 校驗失敗返回表單
    }
    // 保存用戶...
}
  • 靜態(tài)資源處理
    • 確保靜態(tài)資源(如 CSS、JS)路徑不被控制器攔截,通過 WebMvcConfigurer 配置。

完整示例代碼

@Controller
@RequestMapping("/products")
public class ProductController {
 
    // 返回視圖(需配置視圖解析器)
    @GetMapping("/list")
    public String listProducts(Model model) {
        model.addAttribute("products", productService.getAll());
        return "products/list"; // 對應 /templates/products/list.html
    }
 
    // 返回 JSON 數(shù)據(jù)
    @GetMapping("/{id}")
    @ResponseBody
    public Product getProduct(@PathVariable Long id) {
        return productService.getById(id);
    }
 
    // 處理表單提交
    @PostMapping("/save")
    public String saveProduct(@Valid @ModelAttribute Product product, BindingResult result) {
        if (result.hasErrors()) {
            return "products/form";
        }
        productService.save(product);
        return "redirect:/products/list";
    }
}

通過合理使用 @Controller 及其相關(guān)注解,可以構(gòu)建出結(jié)構(gòu)清晰、職責分明的 Web 應用,同時兼顧傳統(tǒng) MVC 和 RESTful API 的開發(fā)需求。

2. @RestController

@RestController 是 Spring 4.0 引入的組合注解,等價于 @Controller + @ResponseBody。它是構(gòu)建 RESTful Web 服務的核心注解,專門用于創(chuàng)建 REST API。

核心作用

  • 簡化 REST API 開發(fā):無需在每個方法上添加 @ResponseBody
  • 自動序列化:方法返回值自動序列化為 JSON/XML 格式
  • 前后端分離支持:適用于前后端分離架構(gòu)的后端 API 開發(fā)

基本用法

簡單 REST 控制器

@RestController
@RequestMapping("/api/users")
public class UserRestController {
    
    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }
    
    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.updateUser(id, user);
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}

與其他注解配合使用

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:3000") // 支持跨域
public class UserRestController {
    
    @GetMapping("/user")
    public User getUser() {
        return new User("Bob", 25); // 自動返回 JSON
    }
    
    // 特定方法覆蓋類級別的映射
    @GetMapping("/admin/user")
    @CrossOrigin(origins = "http://admin.example.com")
    public User getAdminUser() {
        return new User("Admin", 30);
    }
}

特點

  • 組合注解特性:@RestController = @Controller + @ResponseBody
  • 默認返回數(shù)據(jù):所有方法默認返回數(shù)據(jù)而非視圖
  • 自動序列化:方法返回值會自動序列化為 JSON/XML
  • 適用于 RESTful API:專門為 RESTful Web 服務設計
  • 減少樣板代碼:無需在每個方法上添加 @ResponseBody

高級用法示例

1. 自定義響應格式

// 統(tǒng)一響應結(jié)果類
public class Result<T> {
    private int code;
    private String message;
    private T data;
    
    // 構(gòu)造方法、getter 和 setter...
    
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }
}

@RestController
@RequestMapping("/api/users")
public class UserRestController {
    
    @GetMapping
    public Result<List<User>> getUsers() {
        List<User> users = userService.getAllUsers();
        return Result.success(users);
    }
    
    @GetMapping("/{id}")
    public Result<User> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return Result.success(user);
    }
}

2. 異常處理

@RestController
@RequestMapping("/api/users")
public class UserRestController {
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user == null) {
            throw new UserNotFoundException("User not found with id: " + id);
        }
        return user;
    }
}

// 全局異常處理器
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<Result<String>> handleUserNotFound(UserNotFoundException e) {
        Result<String> result = new Result<>();
        result.setCode(404);
        result.setMessage(e.getMessage());
        return ResponseEntity.status(404).body(result);
    }
}

最佳實踐

  1. 專門用于 API 開發(fā):@RestController 專門用于構(gòu)建 RESTful API,不適用于需要返回視圖的場景。

  2. 合理組織 URL 結(jié)構(gòu):使用 @RequestMapping 在類級別定義基礎路徑,方法級別定義具體操作。

  3. 統(tǒng)一響應格式:建議使用統(tǒng)一的響應格式,方便前端處理。

  4. 配合異常處理:結(jié)合 @RestControllerAdvice 進行全局異常處理,提供一致的錯誤響應。

  5. 啟用 CORS:對于前后端分離的應用,合理配置跨域支持。

// 推薦的 RESTful 控制器結(jié)構(gòu)
@RestController
@RequestMapping("/api/v1/users")
@CrossOrigin
public class UserRestController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(
            @PathVariable Long id, 
            @Valid @RequestBody User user) {
        
        return userService.update(id, user)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

通過合理使用 @RestController 注解,可以快速構(gòu)建符合 RESTful 設計規(guī)范的 Web API,滿足現(xiàn)代 Web 應用的開發(fā)需求。

3. @RequestMapping

@RequestMapping 是 Spring MVC 中最基礎和重要的注解之一,用于將 Web 請求映射到具體的處理方法上。它可以應用在類級別或方法級別,提供靈活的請求映射配置。

核心作用

  • URL 映射:將特定 URL 路徑的請求映射到處理方法
  • HTTP 方法限定:指定處理的 HTTP 請求方法(GET、POST、PUT、DELETE 等)
  • 請求條件匹配:基于請求參數(shù)、請求頭等條件進行匹配
  • 內(nèi)容類型控制:指定可處理的請求內(nèi)容類型和返回的內(nèi)容類型

基本用法

類級別使用

@Controller
@RequestMapping("/users")
public class UserController {
    
    // 實際映射路徑為 /users
    @RequestMapping("")
    public String getUsers() {
        return "userList";
    }
    
    // 實際映射路徑為 /users/create
    @RequestMapping("/create")
    public String createUserForm() {
        return "userCreateForm";
    }
    
    // 實際映射路徑為 /users
    @RequestMapping(method = RequestMethod.POST)
    public String createUser() {
        // 創(chuàng)建用戶邏輯
        return "userCreated";
    }
}

方法級別使用

@Controller
public class UserController {
    
    @RequestMapping("/users")
    public String getUsers() {
        return "userList";
    }
    
    @RequestMapping(value = "/users", method = RequestMethod.POST)
    public String createUser() {
        // 創(chuàng)建用戶邏輯
        return "userCreated";
    }
    
    @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
    public String getUser(@PathVariable Long id) {
        // 獲取用戶邏輯
        return "userDetail";
    }
}

主要屬性

屬性類型說明
value/pathString[]指定請求的 URL 路徑,支持 Ant 風格模式(如 /users/*、/users/**)
methodRequestMethod[]指定請求的方法類型(GET、POST、PUT、DELETE、PATCH 等)
paramsString[]指定請求參數(shù)條件(如 “version=1”、“!version”)
headersString[]指定請求頭條件(如 “Accept=text/plain”)
consumesString[]指定處理請求的提交內(nèi)容類型(Content-Type)
producesString[]指定返回內(nèi)容的類型(Accept)

高級用法示例

1. Ant 風格路徑匹配

@Controller
@RequestMapping("/files")
public class FileController {
    
    // 匹配 /files/anyfile.txt
    @RequestMapping("/*.txt")
    public String getTextFile() {
        return "textFileView";
    }
    
    // 匹配 /files/path/to/anyfile.json
    @RequestMapping("/**/*.json")
    public String getJsonFile() {
        return "jsonFileView";
    }
    
    // 匹配 /files/abc 或 /files/def 等
    @RequestMapping("/{fileName:^[a-z]+}")
    public String getFile(@PathVariable String fileName) {
        return "fileView";
    }
}

2. 請求參數(shù)和頭部條件

@Controller
public class ApiController {
    
    // 僅匹配帶有 version=2 參數(shù)的請求
    @RequestMapping(value = "/api/data", params = "version=2")
    public String getDataV2() {
        return "dataV2";
    }
    
    // 僅匹配 Accept 頭部為 application/json 的請求
    @RequestMapping(value = "/api/data", headers = "Accept=application/json")
    @ResponseBody
    public String getJsonData() {
        return "{\"data\":\"json\"}";
    }
    
    // 僅匹配 Content-Type 為 application/json 且 Accept 為 text/html 的請求
    @RequestMapping(value = "/api/data", 
                   consumes = "application/json", 
                   produces = "text/html")
    public String processData() {
        return "processedData";
    }
}

3. 多種 HTTP 方法支持

@Controller
@RequestMapping("/api/users")
public class UserController {
    
    // 支持 GET 和 POST 方法
    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
    public String handleUsers(HttpServletRequest request) {
        if ("GET".equals(request.getMethod())) {
            return "userList";
        } else {
            return "userCreated";
        }
    }
    
    // 支持所有 HTTP 方法
    @RequestMapping("/{id}")
    public String handleUser(@PathVariable Long id, HttpServletRequest request) {
        switch (request.getMethod()) {
            case "GET": return "userDetail";
            case "PUT": return "userUpdated";
            case "DELETE": return "userDeleted";
            default: return "error";
        }
    }
}

最佳實踐

  1. 優(yōu)先使用派生注解:對于簡單的 RESTful API,推薦使用 @GetMapping、@PostMapping 等派生注解,使代碼更清晰。

  2. 合理組織類級別和方法級別映射:將通用路徑前綴放在類級別,具體操作放在方法級別。

  3. 避免過于復雜的映射規(guī)則:復雜的映射會增加維護難度,應盡量保持簡潔。

  4. 使用 produces 和 consumes 明確內(nèi)容類型:有助于提高 API 的可讀性和正確性。

// 推薦的 RESTful 風格
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    
    @PostMapping(consumes = "application/json")
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }
    
    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.updateUser(id, user);
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}

通過合理使用 @RequestMapping 注解及其派生注解,可以構(gòu)建出清晰、規(guī)范的 Web API 接口。

4. @RequestParam

@RequestParam 注解用于將 HTTP 請求參數(shù)(查詢參數(shù)或表單參數(shù))綁定到方法參數(shù)上。它是處理客戶端傳遞參數(shù)的重要注解。

核心作用

  • 參數(shù)綁定:將請求中的參數(shù)值自動綁定到方法參數(shù)
  • 類型轉(zhuǎn)換:自動將字符串參數(shù)轉(zhuǎn)換為相應的 Java 類型
  • 參數(shù)驗證:通過 required 屬性控制參數(shù)是否必須
  • 默認值設置:通過 defaultValue 屬性設置參數(shù)默認值

基本用法

簡單參數(shù)綁定

@GetMapping("/users/search")
public String searchUsers(@RequestParam("name") String name, 
                          @RequestParam("age") Integer age) {
    // 處理請求參數(shù)
    // 例如:/users/search?name=Tom&age=25
    return "userList";
}

可選參數(shù)和默認值

@GetMapping("/users")
public String getUsers(@RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "size", defaultValue = "10") Integer size,
                       @RequestParam(value = "sort", required = false) String sort) {
    // page 和 size 參數(shù)有默認值,即使不傳也會有值
    // sort 參數(shù)是可選的,不傳時為 null
    return "userList";
}

數(shù)組和集合參數(shù)

@GetMapping("/users/batch")
public String batchDelete(@RequestParam("ids") Long[] ids) {
    // 處理多個 ID
    // 例如:/users/batch?ids=1&ids=2&ids=3
    return "batchDeleted";
}

@GetMapping("/users/filter")
public String filterUsers(@RequestParam("tags") List<String> tags) {
    // 處理標簽列表
    // 例如:/users/filter?tags=VIP&tags=Active
    return "filteredList";
}

主要屬性

屬性類型說明
value/nameString指定要綁定的請求參數(shù)名稱
requiredboolean是否必須存在該參數(shù),默認為 true
defaultValueString默認值,當參數(shù)不存在時使用(設置后 required 自動為 false)

高級用法示例

1. 復雜對象參數(shù)綁定

// 用戶搜索條件類
public class UserSearchCriteria {
    private String name;
    private Integer age;
    private String email;
    // getter 和 setter 方法...
}

@Controller
public class UserController {
    
    // 通過 @RequestParam 綁定復雜對象的屬性
    @GetMapping("/users/search")
    public String searchUsers(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) String email,
            Model model) {
        
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setName(name);
        criteria.setAge(age);
        criteria.setEmail(email);
        
        List<User> users = userService.searchUsers(criteria);
        model.addAttribute("users", users);
        return "userList";
    }
}

2. 參數(shù)驗證

@GetMapping("/users/page")
public String getUsersPaginated(
        @RequestParam(value = "page", defaultValue = "1") 
        @Min(1) Integer page,
        @RequestParam(value = "size", defaultValue = "10") 
        @Min(1) @Max(100) Integer size) {
    
    // 使用 Bean Validation 進行參數(shù)驗證
    // page 必須大于等于 1
    // size 必須在 1-100 之間
    return "userList";
}

最佳實踐

  1. 合理使用 defaultValue:對于分頁、排序等場景,設置合理的默認值可以提高用戶體驗。

  2. 注意 required 屬性:設置了 defaultValue 后,required 屬性會自動設為 false。

  3. 類型轉(zhuǎn)換注意事項:確保請求參數(shù)能夠正確轉(zhuǎn)換為目標類型,避免類型轉(zhuǎn)換異常。

  4. 處理集合參數(shù):對于需要傳遞多個同名參數(shù)的場景,可以使用數(shù)組或集合類型。

// 推薦的參數(shù)處理方式
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 分頁查詢
    @GetMapping
    public Page<User> getUsers(
            @RequestParam(value = "page", defaultValue = "0") int page,
            @RequestParam(value = "size", defaultValue = "20") int size,
            @RequestParam(value = "sort", defaultValue = "id") String sort) {
        
        return userService.getUsers(PageRequest.of(page, size, Sort.by(sort)));
    }
    
    // 搜索功能
    @GetMapping("/search")
    public List<User> searchUsers(
            @RequestParam(value = "keyword", required = false) String keyword,
            @RequestParam(value = "department", required = false) String department) {
        
        return userService.searchUsers(keyword, department);
    }
}

通過合理使用 @RequestParam 注解,可以輕松處理各種請求參數(shù)場景,使 Web 接口更加靈活和易用。

5. @PathVariable

@PathVariable 注解用于將 URI 模板變量綁定到方法參數(shù)上,是 RESTful API 設計中的重要注解。它允許從 URL 路徑中提取變量值。

核心作用

  • 路徑變量提取:從 URL 路徑中提取指定的變量值
  • RESTful 風格支持:支持 RESTful 風格的 URL 設計
  • 類型自動轉(zhuǎn)換:自動將路徑變量轉(zhuǎn)換為相應的 Java 類型
  • 正則表達式支持:支持使用正則表達式對路徑變量進行約束

基本用法

簡單路徑變量

@GetMapping("/users/{id}")
public String getUser(@PathVariable("id") Long id) {
    // 處理 /users/123 這樣的請求
    // id 參數(shù)值為 123
    return "userDetail";
}

// 當方法參數(shù)名與路徑變量名一致時,可以省略 value 屬性
@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id) {
    return "userDetail";
}

多個路徑變量

// 多個路徑變量
@GetMapping("/users/{userId}/orders/{orderId}")
public String getOrder(@PathVariable("userId") Long userId, 
                       @PathVariable("orderId") Long orderId) {
    return "orderDetail";
}

// 混合使用路徑變量和請求參數(shù)
@GetMapping("/users/{userId}/orders")
public String getUserOrders(@PathVariable("userId") Long userId,
                           @RequestParam(value = "status", required = false) String status) {
    return "orderList";
}

主要屬性

屬性類型說明
value/nameString指定要綁定的路徑變量名稱
requiredboolean是否必須存在該路徑變量,默認為 true

高級用法示例

1. 正則表達式約束

@RestController
public class FileController {
    
    // 限制 id 只能是數(shù)字
    @GetMapping("/files/{id:\\d+}")
    public String getFile(@PathVariable Long id) {
        return "fileContent";
    }
    
    // 限制文件名格式
    @GetMapping("/images/{filename:.+\\.(jpg|png|gif)}")
    public String getImage(@PathVariable String filename) {
        return "imageContent";
    }
    
    // 日期格式約束
    @GetMapping("/events/{date:\\d{4}-\\d{2}-\\d{2}}")
    public String getEvent(@PathVariable("date") String date) {
        return "eventDetail";
    }
}

2. 復雜路徑變量處理

@RestController
@RequestMapping("/api")
public class ResourceController {
    
    // 處理版本化的 API
    @GetMapping("/v{version:\\d+}/users/{userId}")
    public String getUser(@PathVariable Integer version,
                         @PathVariable Long userId) {
        if (version < 2) {
            // 返回舊版本數(shù)據(jù)格式
            return "userOldFormat";
        } else {
            // 返回新版本數(shù)據(jù)格式
            return "userNewFormat";
        }
    }
    
    // 處理多級路徑
    @GetMapping("/categories/{categoryPath:.+}")
    public String getCategory(@PathVariable String categoryPath) {
        // categoryPath 可以包含多級路徑,如 "electronics/computers/laptops"
        String[] paths = categoryPath.split("/");
        return "categoryDetail";
    }
}

最佳實踐

  1. 路徑變量命名規(guī)范:使用有意義的變量名,提高代碼可讀性。

  2. 類型安全:選擇合適的 Java 類型,避免類型轉(zhuǎn)換異常。

  3. 正則表達式約束:對路徑變量使用正則表達式進行約束,提高 API 的健壯性。

  4. 避免敏感信息:不要在路徑變量中傳遞敏感信息,如密碼、密鑰等。

// 推薦的 RESTful 風格設計
@RestController
@RequestMapping("/api")
public class UserController {
    
    // 獲取用戶信息
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    
    // 獲取用戶的訂單
    @GetMapping("/users/{userId}/orders")
    public List<Order> getUserOrders(@PathVariable Long userId) {
        return orderService.getOrdersByUserId(userId);
    }
    
    // 獲取訂單詳情
    @GetMapping("/users/{userId}/orders/{orderId}")
    public Order getOrder(@PathVariable Long userId, 
                         @PathVariable Long orderId) {
        return orderService.getOrder(userId, orderId);
    }
}

通過合理使用 @PathVariable 注解,可以構(gòu)建出符合 RESTful 設計規(guī)范的 Web API,使 URL 更加直觀和易于理解。

6. @GetMapping

@GetMapping 是 Spring 4.3 引入的組合注解,等價于 @RequestMapping(method = RequestMethod.GET)。它是處理 HTTP GET 請求的快捷方式,專門用于數(shù)據(jù)查詢操作。

核心作用

  • 簡化 GET 請求映射:替代 @RequestMapping(method = RequestMethod.GET)
  • 語義明確:明確表示該方法處理 GET 請求
  • 提高可讀性:使代碼更加簡潔和易讀

基本用法

簡單查詢操作

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 查詢所有用戶
    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    // 根據(jù) ID 查詢用戶
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    
    // 帶查詢參數(shù)的 GET 請求
    @GetMapping(params = "name")
    public List<User> getUsersByName(@RequestParam String name) {
        return userService.getUsersByName(name);
    }
}

復雜查詢場景

@RestController
@RequestMapping("/api/products")
public class ProductController {
    
    // 分頁查詢
    @GetMapping
    public Page<Product> getProducts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "name") String sortBy) {
        
        return productService.getProducts(PageRequest.of(page, size, Sort.by(sortBy)));
    }
    
    // 條件查詢
    @GetMapping("/search")
    public List<Product> searchProducts(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String category,
            @RequestParam(required = false) BigDecimal minPrice,
            @RequestParam(required = false) BigDecimal maxPrice) {
        
        return productService.searchProducts(keyword, category, minPrice, maxPrice);
    }
    
    // 查詢統(tǒng)計信息
    @GetMapping("/count")
    public long getProductCount() {
        return productService.count();
    }
}

主要屬性

@GetMapping 注解繼承了 @RequestMapping 的所有屬性:

屬性類型說明
value/pathString[]指定請求的 URL 路徑
paramsString[]指定請求參數(shù)條件
headersString[]指定請求頭條件
consumesString[]指定處理請求的提交內(nèi)容類型
producesString[]指定返回內(nèi)容的類型

高級用法示例

1. 條件映射

@RestController
@RequestMapping("/api/data")
public class DataController {
    
    // 僅當請求包含 version=2 參數(shù)時匹配
    @GetMapping(params = "version=2")
    public String getDataV2() {
        return "data version 2";
    }
    
    // 僅當請求包含 format=json 參數(shù)時匹配
    @GetMapping(params = "format=json", produces = "application/json")
    @ResponseBody
    public Map<String, Object> getJsonData() {
        Map<String, Object> data = new HashMap<>();
        data.put("message", "json data");
        return data;
    }
    
    // 僅當 Accept 頭部為 text/xml 時匹配
    @GetMapping(produces = "text/xml")
    public String getXmlData() {
        return "<data>xml data</data>";
    }
}

2. 與其他注解配合

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 結(jié)合緩存注解
    @GetMapping("/{id}")
    @Cacheable(value = "users", key = "#id")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    
    // 結(jié)合權(quán)限控制
    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }
    
    // 異步處理
    @GetMapping("/async")
    public Callable<String> getAsyncData() {
        return () -> {
            // 模擬耗時操作
            Thread.sleep(1000);
            return "async data";
        };
    }
}

最佳實踐

  1. 專門用于查詢操作:@GetMapping 專門用于處理查詢請求,符合 HTTP 方法語義。

  2. 冪等性保證:GET 請求應該是冪等的,不應產(chǎn)生副作用。

  3. 合理使用緩存:對于頻繁查詢的數(shù)據(jù),可以結(jié)合緩存機制提高性能。

  4. 避免敏感信息:不要在 GET 請求的 URL 中傳遞敏感信息,因為 URL 可能被記錄在日志中。

  5. 參數(shù)驗證:對于復雜的查詢參數(shù),應進行適當?shù)尿炞C。

// 推薦的查詢接口設計
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 基礎查詢
    @GetMapping
    public ResponseEntity<Page<User>> getUsers(
            @RequestParam(defaultValue = "0") @Min(0) int page,
            @RequestParam(defaultValue = "10") @Min(1) @Max(100) int size) {
        
        Page<User> users = userService.findAll(PageRequest.of(page, size));
        return ResponseEntity.ok(users);
    }
    
    // 條件查詢
    @GetMapping(params = "name")
    public ResponseEntity<List<User>> getUsersByName(
            @RequestParam String name,
            @RequestParam(defaultValue = "false") boolean exact) {
        
        List<User> users = exact ? 
                userService.findByName(name) : 
                userService.findByNameContaining(name);
        return ResponseEntity.ok(users);
    }
    
    // 統(tǒng)計查詢
    @GetMapping("/statistics")
    public ResponseEntity<Map<String, Object>> getUserStatistics() {
        Map<String, Object> statistics = userService.getStatistics();
        return ResponseEntity.ok(statistics);
    }
}

通過合理使用 @GetMapping 注解,可以構(gòu)建出語義清晰、易于維護的查詢接口,提高 Web API 的質(zhì)量和可讀性。

7. @PostMapping

@PostMapping 是 Spring 4.3 引入的組合注解,等價于 @RequestMapping(method = RequestMethod.POST)。它是處理 HTTP POST 請求的快捷方式,專門用于創(chuàng)建資源和提交數(shù)據(jù)操作。

核心作用

  • 簡化 POST 請求映射:替代 @RequestMapping(method = RequestMethod.POST)
  • 語義明確:明確表示該方法處理 POST 請求
  • 提高可讀性:使代碼更加簡潔和易讀
  • 資源創(chuàng)建:主要用于創(chuàng)建新資源

基本用法

創(chuàng)建資源

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 創(chuàng)建新用戶
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
    
    // 創(chuàng)建用戶的訂單
    @PostMapping("/{userId}/orders")
    public ResponseEntity<Order> createOrder(
            @PathVariable Long userId, 
            @RequestBody Order order) {
        
        Order savedOrder = orderService.createOrder(userId, order);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedOrder);
    }
}

表單提交處理

@Controller
@RequestMapping("/users")
public class UserController {
    
    // 處理表單提交
    @PostMapping("/register")
    public String registerUser(@ModelAttribute User user, BindingResult result) {
        if (result.hasErrors()) {
            return "registerForm";
        }
        
        userService.save(user);
        return "redirect:/users/" + user.getId();
    }
    
    // 文件上傳
    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                  RedirectAttributes redirectAttributes) {
        
        // 處理文件上傳邏輯
        redirectAttributes.addFlashAttribute("message", 
                "文件上傳成功: " + file.getOriginalFilename());
        return "redirect:/users/status";
    }
}

主要屬性

@PostMapping 注解繼承了 @RequestMapping 的所有屬性:

屬性類型說明
value/pathString[]指定請求的 URL 路徑
paramsString[]指定請求參數(shù)條件
headersString[]指定請求頭條件
consumesString[]指定處理請求的提交內(nèi)容類型
producesString[]指定返回內(nèi)容的類型

高級用法示例

1. 內(nèi)容類型限定

@RestController
@RequestMapping("/api/data")
public class DataController {
    
    // 僅處理 JSON 格式的請求
    @PostMapping(consumes = "application/json")
    public ResponseEntity<String> handleJsonData(@RequestBody Map<String, Object> data) {
        // 處理 JSON 數(shù)據(jù)
        return ResponseEntity.ok("JSON data processed");
    }
    
    // 僅處理 XML 格式的請求
    @PostMapping(consumes = "application/xml", produces = "application/xml")
    public ResponseEntity<String> handleXmlData(@RequestBody String xmlData) {
        // 處理 XML 數(shù)據(jù)
        String response = "<response>XML data processed</response>";
        return ResponseEntity.ok(response);
    }
    
    // 僅處理表單數(shù)據(jù)
    @PostMapping(consumes = "application/x-www-form-urlencoded")
    public ResponseEntity<String> handleFormData(@RequestParam Map<String, String> formData) {
        // 處理表單數(shù)據(jù)
        return ResponseEntity.ok("Form data processed");
    }
}

2. 與其他注解配合

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 結(jié)合驗證注解
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user, 
                                          BindingResult result) {
        if (result.hasErrors()) {
            return ResponseEntity.badRequest().build();
        }
        
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
    
    // 結(jié)合事務注解
    @PostMapping("/batch")
    @Transactional
    public ResponseEntity<List<User>> createUsers(@RequestBody List<User> users) {
        List<User> savedUsers = userService.saveAll(users);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUsers);
    }
    
    // 結(jié)合安全注解
    @PostMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<User> createAdminUser(@RequestBody User user) {
        user.setRole("ADMIN");
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
}

最佳實踐

  1. 冪等性考慮:POST 請求通常不是冪等的,多次執(zhí)行會產(chǎn)生不同的結(jié)果。

  2. 返回 201 狀態(tài)碼:創(chuàng)建資源成功時應返回 HTTP 201 (CREATED) 狀態(tài)碼。

  3. 返回 Location 頭部:創(chuàng)建資源后,應在響應中包含 Location 頭部,指向新創(chuàng)建的資源。

  4. 參數(shù)驗證:對傳入的數(shù)據(jù)進行驗證,確保數(shù)據(jù)的完整性和正確性。

  5. 事務處理:對于涉及多個操作的復雜創(chuàng)建邏輯,應使用事務確保數(shù)據(jù)一致性。

// 推薦的資源創(chuàng)建接口設計
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user, 
                                          HttpServletRequest request) {
        
        // 保存用戶
        User savedUser = userService.save(user);
        
        // 構(gòu)建資源 URI
        URI location = ServletUriComponentsBuilder
                .fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedUser.getId())
                .toUri();
        
        // 返回 201 狀態(tài)碼和 Location 頭部
        return ResponseEntity.created(location).body(savedUser);
    }
    
    // 批量創(chuàng)建
    @PostMapping("/batch")
    public ResponseEntity<List<User>> createUsers(@Valid @RequestBody List<User> users) {
        if (users.size() > 100) {
            return ResponseEntity.badRequest().build();
        }
        
        List<User> savedUsers = userService.saveAll(users);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUsers);
    }
}

通過合理使用 @PostMapping 注解,可以構(gòu)建出符合 HTTP 語義的資源創(chuàng)建接口,提供良好的 RESTful API 體驗。

8. @DeleteMapping

@DeleteMapping 是 Spring 4.3 引入的組合注解,等價于 @RequestMapping(method = RequestMethod.DELETE)。它是處理 HTTP DELETE 請求的快捷方式,專門用于刪除資源操作。

核心作用

  • 簡化 DELETE 請求映射:替代 @RequestMapping(method = RequestMethod.DELETE)
  • 語義明確:明確表示該方法處理 DELETE 請求
  • 提高可讀性:使代碼更加簡潔和易讀
  • 資源刪除:主要用于刪除指定資源

基本用法

刪除單個資源

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 根據(jù) ID 刪除用戶
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
        return ResponseEntity.noContent().build();
    }
    
    // 條件刪除
    @DeleteMapping(params = "status")
    public ResponseEntity<Void> deleteUsersByStatus(@RequestParam String status) {
        userService.deleteByStatus(status);
        return ResponseEntity.noContent().build();
    }
}

批量刪除

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 批量刪除用戶
    @DeleteMapping("/batch")
    public ResponseEntity<Void> deleteUsers(@RequestBody List<Long> ids) {
        userService.deleteAllById(ids);
        return ResponseEntity.noContent().build();
    }
    
    // 刪除所有用戶(謹慎使用)
    @DeleteMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Void> deleteAllUsers() {
        userService.deleteAll();
        return ResponseEntity.noContent().build();
    }
}

主要屬性

@DeleteMapping 注解繼承了 @RequestMapping 的所有屬性:

屬性類型說明
value/pathString[]指定請求的 URL 路徑
paramsString[]指定請求參數(shù)條件
headersString[]指定請求頭條件
consumesString[]指定處理請求的提交內(nèi)容類型
producesString[]指定返回內(nèi)容的類型

高級用法示例

1. 軟刪除實現(xiàn)

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 軟刪除:標記為已刪除而不是物理刪除
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> softDeleteUser(@PathVariable Long id) {
        userService.softDelete(id);
        return ResponseEntity.noContent().build();
    }
    
    // 永久刪除
    @DeleteMapping("/{id}/permanent")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Void> permanentDeleteUser(@PathVariable Long id) {
        userService.permanentDelete(id);
        return ResponseEntity.noContent().build();
    }
}

2. 關(guān)聯(lián)刪除

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // 刪除用戶及其關(guān)聯(lián)數(shù)據(jù)
    @DeleteMapping("/{id}")
    @Transactional
    public ResponseEntity<Void> deleteUserWithRelations(
            @PathVariable Long id, 
            @RequestParam(defaultValue = "false") boolean cascade) {
        
        if (cascade) {
            // 級聯(lián)刪除關(guān)聯(lián)數(shù)據(jù)
            orderService.deleteByUserId(id);
            userService.deleteById(id);
        } else {
            // 檢查是否有關(guān)聯(lián)數(shù)據(jù)
            if (orderService.existsByUserId(id)) {
                return ResponseEntity.status(HttpStatus.CONFLICT).build();
            }
            userService.deleteById(id);
        }
        
        return ResponseEntity.noContent().build();
    }
}

最佳實踐

  1. 冪等性:DELETE 請求應該是冪等的,多次刪除同一個資源應該返回相同的結(jié)果。

  2. 返回 204 狀態(tài)碼:刪除成功時通常返回 HTTP 204 (NO CONTENT) 狀態(tài)碼。

  3. 安全性考慮:刪除操作應該謹慎處理,特別是批量刪除和刪除所有數(shù)據(jù)的操作。

  4. 權(quán)限控制:刪除敏感資源時應進行權(quán)限驗證。

  5. 軟刪除:對于重要數(shù)據(jù),建議使用軟刪除而不是物理刪除。

// 推薦的刪除接口設計
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(
            @PathVariable Long id, 
            Authentication authentication) {
        
        // 檢查資源是否存在
        if (!userService.existsById(id)) {
            return ResponseEntity.notFound().build();
        }
        
        // 檢查權(quán)限
        if (!userService.canDelete(id, authentication)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }
        
        // 執(zhí)行刪除
        userService.deleteById(id);
        
        // 返回 204 狀態(tài)碼
        return ResponseEntity.noContent().build();
    }
    
    // 批量刪除
    @DeleteMapping("/batch")
    public ResponseEntity<Map<String, Object>> deleteUsers(@RequestBody List<Long> ids) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            int deletedCount = userService.deleteAllById(ids);
            result.put("deletedCount", deletedCount);
            result.put("totalCount", ids.size());
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            result.put("error", e.getMessage());
            return ResponseEntity.badRequest().body(result);
        }
    }
}

通過合理使用 @DeleteMapping 注解,可以構(gòu)建出符合 HTTP 語義的資源刪除接口,提供安全可靠的刪除操作。

9. @ResponseBody

@ResponseBody 是 Spring MVC 中的重要注解,用于指示方法返回值應直接寫入 HTTP 響應體中,而不是被視圖解析器解析為視圖名稱。它是構(gòu)建 RESTful API 的關(guān)鍵注解之一。

核心作用

  • 響應體直接輸出:將方法返回值直接寫入 HTTP 響應體
  • 自動序列化:自動將 Java 對象序列化為 JSON、XML 等格式
  • 視圖解析繞過:跳過視圖解析器,直接返回數(shù)據(jù)
  • RESTful 支持:支持構(gòu)建 RESTful Web 服務

基本用法

在方法上使用

@Controller
@RequestMapping("/api")
public class ApiController {
    
    // 返回 JSON 數(shù)據(jù)
    @GetMapping("/user")
    @ResponseBody
    public User getUser() {
        return new User("Alice", 30); // 自動轉(zhuǎn)換為 JSON
    }
    
    // 返回字符串數(shù)據(jù)
    @GetMapping("/message")
    @ResponseBody
    public String getMessage() {
        return "Hello, World!";
    }
    
    // 返回集合數(shù)據(jù)
    @GetMapping("/users")
    @ResponseBody
    public List<User> getUsers() {
        return Arrays.asList(new User("Alice", 30), new User("Bob", 25));
    }
}

在類上使用

// 等價于在每個方法上添加 @ResponseBody
@RestController  // @RestController = @Controller + @ResponseBody
@RequestMapping("/api/users")
public class UserRestController {
    
    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

特點

  • 自動序列化:返回值會自動序列化為 JSON/XML
  • 繞過視圖解析:不經(jīng)過視圖解析器
  • 適用于 RESTful API:專門用于構(gòu)建 RESTful Web 服務
  • 內(nèi)容協(xié)商:根據(jù)請求的 Accept 頭部返回相應格式的數(shù)據(jù)

高級用法示例

1. 自定義序列化

@Controller
public class DataController {
    
    // 返回自定義格式的數(shù)據(jù)
    @GetMapping(value = "/data", produces = "application/json")
    @ResponseBody
    public String getJsonData() {
        return "{"name": "Alice", "age": 30}";
    }
    
    // 返回 XML 數(shù)據(jù)
    @GetMapping(value = "/data.xml", produces = "application/xml")
    @ResponseBody
    public String getXmlData() {
        return "<user><name>Alice</name><age>30</age></user>";
    }
    
    // 返回二進制數(shù)據(jù)
    @GetMapping(value = "/image", produces = "image/png")
    @ResponseBody
    public byte[] getImage() throws IOException {
        // 返回圖片數(shù)據(jù)
        return Files.readAllBytes(Paths.get("path/to/image.png"));
    }
}

2. ResponseEntity 結(jié)合使用

@Controller
public class UserController {
    
    // 使用 ResponseEntity 提供更多控制
    @GetMapping("/user/{id}")
    @ResponseBody
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user != null) {
            return ResponseEntity.ok(user);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    // 帶自定義頭部的響應
    @PostMapping("/user")
    @ResponseBody
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.save(user);
        
        return ResponseEntity
                .created(URI.create("/api/user/" + savedUser.getId()))
                .header("X-Custom-Header", "CustomValue")
                .body(savedUser);
    }
}

最佳實踐

  1. 優(yōu)先使用 @RestController:對于 RESTful API,優(yōu)先使用 @RestController 而不是在每個方法上添加 @ResponseBody。

  2. 合理設置 Content-Type:使用 produces 屬性明確指定返回內(nèi)容類型。

  3. 異常處理:結(jié)合 @ExceptionHandler 或 @ControllerAdvice 處理序列化異常。

  4. 大數(shù)據(jù)處理:對于大文件下載等場景,考慮使用 StreamingResponseBody。

// 推薦的 RESTful API 設計
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 查詢所有用戶
    @GetMapping(produces = "application/json")
    public ResponseEntity<List<User>> getUsers() {
        List<User> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    // 根據(jù) ID 查詢用戶
    @GetMapping(value = "/{id}", produces = "application/json")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    // 創(chuàng)建用戶
    @PostMapping(consumes = "application/json", produces = "application/json")
    public ResponseEntity<User> createUser(@Valid @RequestBody User user, 
                                          HttpServletRequest request) {
        
        User savedUser = userService.save(user);
        
        // 構(gòu)建資源 URI
        URI location = ServletUriComponentsBuilder
                .fromContextPath(request)
                .path("/api/users/{id}")
                .buildAndExpand(savedUser.getId())
                .toUri();
        
        return ResponseEntity.created(location).body(savedUser);
    }
}

通過合理使用 @ResponseBody 注解,可以輕松構(gòu)建出能夠返回各種格式數(shù)據(jù)的 Web API,滿足現(xiàn)代 Web 應用的多樣化需求。

10. @Service

@Service 是 Spring Framework 中用于標記業(yè)務邏輯層組件的核心注解,屬于 Spring 的典型分層架構(gòu)注解之一。它將類標識為 Spring 容器管理的服務 Bean,通常用于處理業(yè)務邏輯。

核心作用

  • 業(yè)務邏輯標識:明確標識業(yè)務邏輯層組件,提高代碼可讀性
  • 自動注冊:標記的類會自動注冊為 Spring 容器中的 Bean
  • 依賴注入支持:可被其他組件通過 @Autowired 等注解注入使用
  • 事務管理集成:與 Spring 事務管理機制無縫集成

基本用法

簡單服務類

@Service
public class UserService {
    
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
    
    public List<User> getAllUsers() {
        return userMapper.findAll();
    }
    
    public User saveUser(User user) {
        return userMapper.save(user);
    }
}

帶名稱的服務類

@Service("userService")
public class UserServiceImpl implements UserService {
    
    @Override
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

特點

  • 組件掃描支持:@Service 是 @Component 的特化,會被組件掃描自動發(fā)現(xiàn)
  • 默認單例模式:Spring 容器中默認以單例模式管理服務 Bean
  • 依賴注入支持:可被其他組件通過 @Autowired、@Resource 等注解注入
  • 生命周期管理:支持 @PostConstruct 和 @PreDestroy 等生命周期注解

高級用法示例

1. 事務管理

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Transactional(readOnly = true)
    public User findById(Long id) {
        return userMapper.findById(id);
    }
    
    // 默認具有事務支持
    public User save(User user) {
        User savedUser = userMapper.save(user);
        // 可能的其他業(yè)務邏輯
        return savedUser;
    }
    
    // 需要新事務的方法
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void logUserAction(Long userId, String action) {
        // 記錄用戶操作日志
    }
}

2. 與其他注解配合

@Service
@Scope("prototype") // 每次請求創(chuàng)建新實例
@Primary // 標記為主要實現(xiàn)
public class DefaultUserService implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    @Cacheable("users") // 啟用緩存
    public User findById(Long id) {
        return userRepository.findById(id);
    }
    
    @Override
    @CacheEvict(value = "users", key = "#user.id") // 更新時清除緩存
    public User save(User user) {
        return userRepository.save(user);
    }
}

最佳實踐

  1. 明確業(yè)務邊界:每個服務類應該具有明確的業(yè)務職責,遵循單一職責原則。

  2. 合理使用事務

    • 在服務層配置事務管理
    • 根據(jù)業(yè)務需求設置合適的事務傳播行為
    • 讀取操作使用 readOnly = true 提高性能
  3. 異常處理:在服務層處理業(yè)務異常,避免將底層異常直接拋出。

  4. 接口與實現(xiàn)分離:定義服務接口,通過實現(xiàn)類添加 @Service 注解。

// 推薦的服務層設計
@Service
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserValidator userValidator;
    
    @Override
    public User findById(Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException("User not found: " + id));
    }
    
    @Override
    @Transactional
    public User save(User user) {
        // 參數(shù)驗證
        userValidator.validate(user);
        
        // 保存用戶
        User savedUser = userRepository.save(user);
        
        // 發(fā)布事件
        applicationEventPublisher.publishEvent(new UserSavedEvent(savedUser));
        
        return savedUser;
    }
    
    @Override
    @Transactional
    public void deleteById(Long id) {
        User user = findById(id);
        userRepository.delete(user);
        
        // 清理相關(guān)資源
        cleanupRelatedResources(user);
    }
    
    private void cleanupRelatedResources(User user) {
        // 清理用戶相關(guān)的資源
    }
}

通過合理使用 @Service 注解,可以構(gòu)建出結(jié)構(gòu)清晰、職責分明的業(yè)務邏輯層,提高代碼的可維護性和可測試性。

11. @Autowired

@Autowired 是 Spring Framework 中實現(xiàn)依賴注入(DI)的核心注解之一。它用于自動裝配 Bean 之間的依賴關(guān)系,是 Spring IoC 容器實現(xiàn)控制反轉(zhuǎn)的關(guān)鍵機制。

核心作用

  • 自動裝配:自動將匹配的 Bean 注入到字段、構(gòu)造函數(shù)或方法中
  • 解耦合:降低組件間的耦合度,提高代碼的可測試性和可維護性
  • 簡化配置:減少 XML 配置或 Java 配置的工作量
  • 類型安全:基于類型進行裝配,提供編譯時和運行時的安全性

基本用法

字段注入

@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

構(gòu)造函數(shù)注入

@Service
public class UserService {
    
    private final UserMapper userMapper;
    
    // Spring 4.3+ 后,單構(gòu)造函數(shù)場景下可省略 @Autowired
    @Autowired
    public UserService(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

方法注入

@Service
public class UserService {
    
    private UserMapper userMapper;
    
    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }
    
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

主要屬性

屬性類型說明
requiredboolean是否必須找到匹配的 Bean,默認為 true。設置為 false 時,找不到匹配的 Bean 不會拋出異常

高級用法示例

1. 集合注入

@Service
public class PaymentService {
    
    // 注入所有 PaymentProcessor 的實現(xiàn)
    @Autowired
    private List<PaymentProcessor> paymentProcessors;
    
    // 注入所有 PaymentProcessor 實現(xiàn)及其名稱
    @Autowired
    private Map<String, PaymentProcessor> paymentProcessorMap;
    
    public void processPayment(String type, BigDecimal amount) {
        PaymentProcessor processor = paymentProcessorMap.get(type + "PaymentProcessor");
        if (processor != null) {
            processor.process(amount);
        }
    }
}

2. 泛型注入

@Service
public class GenericService {
    
    // 注入 String 類型的 Repository
    @Autowired
    private GenericRepository<String> stringRepository;
    
    // 注入 Integer 類型的 Repository
    @Autowired
    private GenericRepository<Integer> integerRepository;
}

3. 條件注入

@Service
public class ConditionalService {
    
    // 可選注入,如果找不到 Bean 則為 null
    @Autowired(required = false)
    private OptionalFeature optionalFeature;
    
    public void performOperation() {
        // 使用可選功能
        if (optionalFeature != null) {
            optionalFeature.perform();
        }
        
        // 其他操作
    }
}

最佳實踐

  1. 優(yōu)先使用構(gòu)造函數(shù)注入

    • 保證依賴不可變性(final 字段)
    • 確保依賴完整性(避免 NullPointerException)
    • 提高類的可測試性
  2. 避免循環(huán)依賴

    • 重新設計組件結(jié)構(gòu)
    • 使用 @Lazy 注解延遲加載
    • 考慮使用 Setter 注入解決循環(huán)依賴
  3. 合理使用 required 屬性

    • 對于必須的依賴保持 required = true(默認值)
    • 對于可選的依賴設置 required = false
// 推薦的依賴注入方式
@Service
public class UserService {
    
    private final UserRepository userRepository;
    private final EmailService emailService;
    
    // 構(gòu)造函數(shù)注入(推薦)
    public UserService(UserRepository userRepository, 
                      @Autowired(required = false) EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }
    
    public User createUser(User user) {
        User savedUser = userRepository.save(user);
        
        // 可選功能
        if (emailService != null) {
            emailService.sendWelcomeEmail(savedUser);
        }
        
        return savedUser;
    }
}

通過合理使用 @Autowired 注解,可以實現(xiàn)松耦合、高內(nèi)聚的組件設計,提高代碼的可維護性和可測試性。

12. @Resource

@Resource 是 Java 標準注解(JSR-250)中用于依賴注入的注解,與 Spring 的 @Autowired 注解功能相似但裝配機制不同。它提供了更靈活的裝配方式,支持按名稱或類型進行裝配。

核心作用

  • 標準化依賴注入:作為 Java 標準注解,提供跨框架的依賴注入能力
  • 靈活裝配機制:支持按名稱或類型裝配,優(yōu)先按名稱裝配
  • 減少框架綁定:使用標準注解降低對特定框架的依賴
  • 兼容性支持:在不同 Java EE 兼容框架中保持一致性

基本用法

默認裝配

@Service
public class UserService {
    
    // 按字段名稱裝配,如果找不到則按類型裝配
    @Resource
    private UserMapper userMapper;
    
    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

按名稱裝配

@Service
public class UserService {
    
    // 明確按名稱裝配
    @Resource(name = "userDatabaseMapper")
    private UserMapper userMapper;
    
    // 裝配特定名稱的 DAO
    @Resource(name = "jdbcUserDao")
    private UserDao userDao;
}

按類型裝配

@Service
public class UserService {
    
    // 按類型裝配,忽略字段名稱
    @Resource(type = UserMapper.class)
    private UserMapper userMapper;
}

主要屬性

屬性類型說明
nameString指定要注入的 Bean 名稱,按名稱裝配
typeClass指定要注入的 Bean 類型,按類型裝配

@Autowired 與 @Resource 的區(qū)別

特性@Autowired@Resource
來源Spring 框架Java 標準 (JSR-250)
裝配方式默認按類型裝配默認按名稱裝配,名稱不存在時按類型裝配
屬性requiredname, type
適用場景Spring 特定項目跨框架通用項目
性能略快略慢(需解析名稱和類型)

高級用法示例

1. 混合使用場景

@Service
public class PaymentService {
    
    // 使用 @Resource 按名稱裝配特定支付處理器
    @Resource(name = "alipayProcessor")
    private PaymentProcessor alipayProcessor;
    
    // 使用 @Autowired 按類型裝配所有支付處理器
    @Autowired
    private List<PaymentProcessor> allProcessors;
    
    public void processPayment(String type, BigDecimal amount) {
        switch (type) {
            case "alipay":
                alipayProcessor.process(amount);
                break;
            default:
                // 使用其他處理器
                break;
        }
    }
}

2. 在不同環(huán)境中切換實現(xiàn)

@Component
@Profile("production")
public class ProductionEmailService implements EmailService {
    // 生產(chǎn)環(huán)境實現(xiàn)
}

@Component
@Profile("development")
public class DevelopmentEmailService implements EmailService {
    // 開發(fā)環(huán)境實現(xiàn)
}

@Service
public class NotificationService {
    
    // 在不同環(huán)境中自動切換實現(xiàn)
    @Resource
    private EmailService emailService;
    
    public void sendNotification(String message) {
        emailService.send(message);
    }
}

最佳實踐

  1. 選擇合適的注解

    • 在純 Spring 項目中優(yōu)先使用 @Autowired
    • 在需要跨框架兼容的項目中使用 @Resource
  2. 明確裝配策略

    • 需要精確控制時使用 name 或 type 屬性
    • 一般情況下可依賴默認裝配機制
  3. 保持一致性

    • 在同一項目中保持依賴注入注解的使用一致性
    • 團隊內(nèi)部應制定明確的編碼規(guī)范
// 推薦的 @Resource 使用方式
@Service
public class OrderService {
    
    // 明確按名稱裝配
    @Resource(name = "orderRepository")
    private OrderRepository orderRepository;
    
    // 按類型裝配(適用于單一實現(xiàn))
    @Resource(type = PaymentService.class)
    private PaymentService paymentService;
    
    // 默認裝配(適用于名稱匹配的場景)
    @Resource
    private InventoryService inventoryService;
    
    public void processOrder(Order order) {
        // 處理訂單邏輯
        orderRepository.save(order);
        paymentService.processPayment(order);
        inventoryService.updateInventory(order);
    }
}

通過合理使用 @Resource 注解,可以在享受依賴注入便利的同時,保持代碼的標準化和框架無關(guān)性。

13. @CrossOrigin

@CrossOrigin 是 Spring MVC 中用于處理跨域資源共享(CORS)的注解。它允許您在 Web 應用中輕松配置跨域請求策略,解決瀏覽器同源策略限制。

核心作用

  • 跨域訪問控制:允許指定域的請求訪問當前服務的資源
  • HTTP 方法控制:限制允許的 HTTP 請求方法
  • 請求頭管理:控制允許的請求頭和暴露的響應頭
  • 預檢請求緩存:通過 maxAge 屬性優(yōu)化預檢請求性能

基本用法

類級別使用

@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://localhost:3000")
public class UserController {
    
    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

方法級別使用

@RestController
@RequestMapping("/api")
public class ApiController {
    
    // 允許來自特定域的請求
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/user")
    public User getUser() {
        return new User("Bob", 25);
    }
    
    // 允許多個域的請求
    @CrossOrigin(origins = {"http://localhost:3000", "http://localhost:4000"})
    @GetMapping("/admin")
    public User getAdmin() {
        return new User("Admin", 30);
    }
}

主要屬性

屬性類型說明
originsString[]允許的源地址,支持通配符"*"表示允許所有域
methodsRequestMethod[]允許的 HTTP 方法,默認允許所有標準方法
allowedHeadersString[]允許的請求頭,"*"表示允許所有頭
exposedHeadersString[]瀏覽器可以訪問的響應頭
maxAgelong預檢請求的緩存時間(秒),默認為 1800 秒
allowCredentialsboolean是否允許攜帶憑證(如 Cookie),默認為 false

高級用法示例

1. 全局 CORS 配置

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:3000", "http://localhost:4000")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .exposedHeaders("X-Custom-Header")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

2. 復雜的跨域配置

@RestController
@RequestMapping("/api")
public class ComplexController {
    
    // 允許所有域,但限制方法和頭
    @CrossOrigin(
        origins = "*",
        methods = {RequestMethod.GET, RequestMethod.POST},
        allowedHeaders = {"Content-Type", "Authorization"},
        exposedHeaders = {"X-Total-Count"},
        maxAge = 3600
    )
    @GetMapping("/data")
    public List<Data> getData() {
        return dataService.getAll();
    }
    
    // 需要攜帶憑證的跨域請求
    @CrossOrigin(
        origins = "http://trusted-domain.com",
        allowCredentials = "true"
    )
    @PostMapping("/secure")
    public ResponseEntity<String> secureOperation() {
        return ResponseEntity.ok("Secure operation completed");
    }
}

最佳實踐

  1. 安全性考慮

    • 避免在生產(chǎn)環(huán)境中使用 origins = “*”,除非確實需要
    • 對于需要攜帶憑證的請求,必須指定具體的源地址
    • 限制允許的 HTTP 方法和請求頭
  2. 性能優(yōu)化

    • 合理設置 maxAge 值,減少預檢請求次數(shù)
    • 盡量在類級別而非方法級別配置 CORS
  3. 配置方式選擇

    • 全局配置適用于統(tǒng)一的跨域策略
    • 局部配置適用于特殊接口的跨域需求
// 推薦的生產(chǎn)環(huán)境 CORS 配置
@RestController
@RequestMapping("/api/users")
@CrossOrigin(
    origins = {"https://myapp.example.com", "https://admin.example.com"},
    methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE},
    allowedHeaders = {"Content-Type", "Authorization", "X-Requested-With"},
    exposedHeaders = {"X-Total-Count"},
    maxAge = 3600
)
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public ResponseEntity<List<User>> getUsers() {
        List<User> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
}

通過合理使用 @CrossOrigin 注解,可以有效解決跨域問題,同時確保應用的安全性和性能。

14. @Configuration

@Configuration 是 Spring Framework 中用于定義配置類的核心注解。它標識一個類作為 Spring IoC 容器的配置源,通常與 [@Bean](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_14_annotation_third_bean_manager/src/main/java/com/itheima/config/JdbcConfig.java#L22-L22) 注解配合使用來定義和管理 Bean。

核心作用

  • 配置類標識:標識一個類作為配置類,替代傳統(tǒng)的 XML 配置文件
  • Bean 定義:與 [@Bean](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_14_annotation_third_bean_manager/src/main/java/com/itheima/config/JdbcConfig.java#L22-L22) 注解配合,定義和配置 Spring Bean
  • 組件掃描支持:作為 [@Component](file:///D:/workspace/spring_clouds/10-riskmgmt/perisk/src/main/java/com/citics/riskmgnt/perisk/common/ThreadPoolUtil.java#L23-L23) 的特化版本,可被組件掃描自動發(fā)現(xiàn)
  • 條件化配置:可與 [@Profile](file:///D:/workspace/spring_clouds/10-riskmgmt/amxrisk/src/main/java/com/citics/riskmgnt/amxrisk/config/RestTemplateConfig.java#L23-L23)、[@Conditional](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_11_annotation_aop/src/main/java/com/itheima/config/SpringConfig.java#L9-L9) 等注解結(jié)合,實現(xiàn)條件化配置

基本用法示例

簡單配置類

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserServiceImpl();
    }
    
    @Bean
    public UserMapper userMapper() {
        return new UserMapperImpl();
    }
}

帶屬性注入的配置類

@Configuration
public class DatabaseConfig {
    
    @Value("${database.url}")
    private String databaseUrl;
    
    @Value("${database.username}")
    private String username;
    
    @Value("${database.password}")
    private String password;
    
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(databaseUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
    
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

主要屬性

@Configuration 注解本身沒有屬性,但通常與其他注解配合使用:

注解作用示例
[@PropertySource](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_13_annotation_di/src/main/java/com/itheima/config/SpringConfig.java#L9-L9)加載屬性文件@PropertySource(“classpath:jdbc.properties”)
[@ComponentScan](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_12_annotation_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L8-L8)指定組件掃描路徑@ComponentScan(“com.example”)
[@Import](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_14_annotation_third_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L11-L11)導入其他配置類@Import({ServiceConfig.class, DaoConfig.class})

高級特性

條件化配置

@Configuration
@Profile("production")
public class ProductionDatabaseConfig {
    
    @Bean
    public DataSource dataSource() {
        // 生產(chǎn)環(huán)境數(shù)據(jù)源配置
        return new HikariDataSource();
    }
}

@Configuration
@Profile("development")
public class DevelopmentDatabaseConfig {
    
    @Bean
    public DataSource dataSource() {
        // 開發(fā)環(huán)境數(shù)據(jù)源配置
        return new DriverManagerDataSource();
    }
}

導入其他配置

@Configuration
@ComponentScan("com.example")
@Import({DatabaseConfig.class, SecurityConfig.class})
@PropertySource("classpath:application.properties")
public class MainConfig {
    
    @Bean
    public ApplicationService applicationService() {
        return new ApplicationServiceImpl();
    }
}

最佳實踐

  • 明確配置職責:每個配置類應該有明確的職責,如數(shù)據(jù)庫配置、安全配置等
  • 合理使用 [@Import](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_14_annotation_third_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L11-L11):通過 [@Import](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_14_annotation_third_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L11-L11) 注解組合多個配置類,提高配置的模塊化
  • 屬性注入:使用 [@Value](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_16_spring_junit/src/main/java/com/itheima/config/JdbcConfig.java#L13-L13) 注解注入配置屬性,實現(xiàn)配置與代碼的分離
  • 避免復雜邏輯:配置類中應避免復雜的業(yè)務邏輯,專注于 Bean 的配置
// 推薦的配置類設計
@Configuration
@PropertySource("classpath:app.properties")
@ComponentScan(basePackages = "com.example")
@Import({DatabaseConfig.class, SecurityConfig.class})
public class ApplicationConfig {
    
    @Value("${app.name:MyApplication}")
    private String applicationName;
    
    @Bean
    public ApplicationService applicationService(
            UserService userService, 
            NotificationService notificationService) {
        ApplicationServiceImpl service = new ApplicationServiceImpl();
        service.setUserService(userService);
        service.setNotificationService(notificationService);
        service.setApplicationName(applicationName);
        return service;
    }
}

通過合理使用 @Configuration 注解,可以構(gòu)建出結(jié)構(gòu)清晰、模塊化的配置體系,提高應用的可維護性和可測試性。

15. @Bean

@Bean 是 Spring Framework 中用于在配置類中定義 Bean 的核心注解。它告訴 Spring 容器,被注解的方法將返回一個對象,該對象應該被注冊為 Spring 應用上下文中的 Bean。

核心作用

  • Bean 定義:在配置類中定義和配置 Spring Bean
  • 生命周期管理:通過 initMethod 和 destroyMethod 屬性管理 Bean 的生命周期
  • 依賴注入:方法參數(shù)會自動從容器中獲取并注入
  • Bean 名稱定制:通過 name 屬性自定義 Bean 的名稱

基本用法

簡單 Bean 定義

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService() {
        return new UserServiceImpl();
    }
    
    @Bean
    public UserMapper userMapper() {
        return new UserMapperImpl();
    }
}

依賴其他 Bean

@Configuration
public class AppConfig {
    
    @Bean
    public UserMapper userMapper() {
        return new UserMapperImpl();
    }
    
    // 方法參數(shù)會自動從容器中獲取并注入
    @Bean
    public UserService userService(UserMapper userMapper) {
        UserServiceImpl service = new UserServiceImpl();
        service.setUserMapper(userMapper);
        return service;
    }
}

主要屬性

屬性類型說明
nameString[]Bean 的名稱,默認為方法名
initMethodString初始化方法名,在 Bean 初始化時調(diào)用
destroyMethodString銷毀方法名,在 Bean 銷毀時調(diào)用
autowireCandidateboolean是否作為自動裝配的候選者,默認為 true

高級用法示例

自定義 Bean 名稱和生命周期方法

@Configuration
public class AppConfig {
    
    @Bean(name = "customUserService", initMethod = "initialize", destroyMethod = "cleanup")
    public UserService userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setSomeProperty("value");
        return userService;
    }
    
    @Bean("namedMapper")
    public UserMapper userMapper() {
        return new UserMapperImpl();
    }
}

作用域配置

@Configuration
public class AppConfig {
    
    @Bean
    @Scope("singleton") // 默認作用域
    public UserService singletonUserService() {
        return new UserServiceImpl();
    }
    
    @Bean
    @Scope("prototype")
    public UserMapper prototypeUserMapper() {
        return new UserMapperImpl();
    }
    
    @Bean
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public ShoppingCart sessionCart() {
        return new ShoppingCart();
    }
}

最佳實踐

  1. 方法參數(shù)注入:利用方法參數(shù)自動注入依賴,比手動從容器獲取更簡潔
  2. 合理命名:對于需要自定義名稱的 Bean,使用 name 屬性明確指定
  3. 生命周期管理:對于需要初始化或清理操作的 Bean,配置 initMethod 和 destroyMethod
  4. 作用域選擇:根據(jù) Bean 的使用場景選擇合適的作用域
// 推薦的 @Bean 使用方式
@Configuration
public class DatabaseConfig {
    
    @Value("${database.pool.size:10}")
    private int poolSize;
    
    @Bean(name = "primaryDataSource", initMethod = "init", destroyMethod = "close")
    public DataSource primaryDataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setMaximumPoolSize(poolSize);
        // 其他配置...
        return dataSource;
    }
    
    @Bean
    @Scope("prototype")
    public JdbcTemplate jdbcTemplate(DataSource primaryDataSource) {
        return new JdbcTemplate(primaryDataSource);
    }
    
    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager txManager) {
        return new TransactionTemplate(txManager);
    }
}

通過合理使用 @Bean 注解,可以靈活地定義和配置 Spring 容器中的各種 Bean,滿足不同場景的需求。

16. @Component

@Component 是 Spring Framework 中最基本的組件注解,用于標記任何 Spring 管理的組件。它是其他特定組件注解(如 [@Controller](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_19_springmvc_demo/src/main/java/com/itheima/controller/UserController.java#L9-L9)、[@Service](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/userauth/service/impl/UserAuthServiceImpl.java#L17-L17)、[@Repository](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/citicRuleCheck/dao/CiticRuleCheckDao.java#L10-L10))的基礎注解。

核心作用

  • 通用組件標識:標記一個類作為 Spring 容器管理的組件
  • 自動注冊:被 [@ComponentScan](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_12_annotation_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L8-L8) 掃描并注冊為 Bean
  • 依賴注入支持:可被其他組件通過 [@Autowired](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_13_annotation_di/src/main/java/com/itheima/service/impl/UserServiceImpl.java#L12-L12)、[@Resource](file:///D:/workspace/spring_clouds/10-riskmgmt/auth/src/main/java/com/citics/auth/login/service/impl/LoginServiceImpl.java#L29-L29) 等注解注入使用
  • 基礎注解:是 [@Controller](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_19_springmvc_demo/src/main/java/com/itheima/controller/UserController.java#L9-L9)、[@Service](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/userauth/service/impl/UserAuthServiceImpl.java#L17-L17)、[@Repository](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/citicRuleCheck/dao/CiticRuleCheckDao.java#L10-L10) 等注解的基礎

基本用法

簡單組件

@Component
public class MyComponent {
    
    public void doSomething() {
        System.out.println("執(zhí)行某些操作");
    }
}

帶名稱的組件

@Component("myCustomComponent")
public class MyComponent {
    
    public void performAction() {
        System.out.println("執(zhí)行操作");
    }
}

特點

  • 通用性:適用于任何 Spring 管理的組件
  • 自動發(fā)現(xiàn):配合 [@ComponentScan](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_12_annotation_bean_manager/src/main/java/com/itheima/config/SpringConfig.java#L8-L8) 可自動注冊為 Bean
  • 可注入性:可被其他組件注入使用
  • 繼承性:其他組件注解的基礎注解

與其他注解的關(guān)系

注解用途說明
[@Repository](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/citicRuleCheck/dao/CiticRuleCheckDao.java#L10-L10)持久層組件專門用于數(shù)據(jù)訪問層,提供持久層異常轉(zhuǎn)換
[@Service](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/userauth/service/impl/UserAuthServiceImpl.java#L17-L17)業(yè)務層組件專門用于業(yè)務邏輯層
[@Controller](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_19_springmvc_demo/src/main/java/com/itheima/controller/UserController.java#L9-L9)控制層組件專門用于 Web 控制層
[@Component](file:///D:/workspace/spring_clouds/10-riskmgmt/perisk/src/main/java/com/citics/riskmgnt/perisk/common/ThreadPoolUtil.java#L23-L23)通用組件適用于任何組件,是上述注解的基礎

這些注解都是 @Component 的特化版本,具有相同的功能但語義更明確。

高級用法示例

條件化組件

@Component
@Profile("development")
public class DevelopmentService {
    
    public void performAction() {
        System.out.println("開發(fā)環(huán)境下的操作");
    }
}

@Component
@Profile("production")
public class ProductionService {
    
    public void performAction() {
        System.out.println("生產(chǎn)環(huán)境下的操作");
    }
}

帶作用域的組件

@Component
@Scope("prototype")
public class PrototypeComponent {
    
    public void doSomething() {
        System.out.println("原型組件操作");
    }
}

@Component
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionScopedComponent {
    
    public void doSessionWork() {
        System.out.println("會話范圍組件操作");
    }
}

最佳實踐

  1. 語義化選擇:優(yōu)先使用語義更明確的注解([@Repository](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/citicRuleCheck/dao/CiticRuleCheckDao.java#L10-L10)、[@Service](file:///D:/workspace/spring_clouds/10-riskmgmt/spec/src/main/java/com/citics/riskmgnt/spec/userauth/service/impl/UserAuthServiceImpl.java#L17-L17)、[@Controller](file:///D:/workspace/spring_clouds/09-spring/src/main/java/com/spring/spring_19_springmvc_demo/src/main/java/com/itheima/controller/UserController.java#L9-L9)),只在沒有合適注解時使用 [@Component](file:///D:/workspace/spring_clouds/10-riskmgmt/perisk/src/main/java/com/citics/riskmgnt/perisk/common/ThreadPoolUtil.java#L23-L23)
  2. 命名規(guī)范:對于需要自定義名稱的組件,明確指定名稱
  3. 組件職責:每個組件應有明確的職責,遵循單一職責原則
// 推薦的組件設計
@Component
public class FileStorageService {
    
    private final StorageProperties storageProperties;
    
    // 構(gòu)造函數(shù)注入(推薦)
    public FileStorageService(StorageProperties storageProperties) {
        this.storageProperties = storageProperties;
    }
    
    public void saveFile(MultipartFile file) {
        // 文件保存邏輯
        String location = storageProperties.getLocation();
        // 實際保存操作
    }
    
    public byte[] loadFile(String filename) {
        // 文件加載邏輯
        return new byte[0];
    }
}

通過合理使用 @Component 及其特化注解,可以構(gòu)建出結(jié)構(gòu)清晰、職責明確的 Spring 應用程序,提高代碼的可維護性和可讀性。

17. @Value

@Value 是 Spring Framework 中用于注入屬性值的核心注解。它可以將配置文件中的屬性值、系統(tǒng)屬性、環(huán)境變量等注入到 Spring 管理的 Bean 屬性中。

核心作用

  • 屬性注入:將外部配置屬性注入到 Bean 的字段或方法參數(shù)中
  • 表達式支持:支持 Spring Expression Language (SpEL) 表達式
  • 默認值設置:可以為屬性設置默認值,提高應用的健壯性
  • 配置分離:實現(xiàn)配置與代碼的分離,便于維護和部署

基本用法

注入簡單屬性值

@Component
public class DatabaseConfig {
    
    @Value("${database.url}")
    private String databaseUrl;
    
    @Value("${database.username}")
    private String username;
    
    @Value("${database.password}")
    private String password;
    
    // 使用注入的屬性
    public DataSource createDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl(databaseUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

設置默認值

@Component
public class AppConfig {
    
    // 如果配置文件中沒有定義 server.port,則使用默認值 8080
    @Value("${server.port:8080}")
    private int serverPort;
    
    // 字符串默認值
    @Value("${app.name:MyApplication}")
    private String appName;
    
    // 數(shù)組默認值
    @Value("${app.servers:server1,server2,server3}")
    private String[] servers;
}

主要屬性

@Value 注解只有一個 value 屬性,用于指定要注入的值:

屬性類型說明
valueString指定要注入的屬性值或表達式

高級用法示例

使用 SpEL 表達式

@Component
public class ExpressionConfig {
    
    // 字面量表達式
    @Value("#{10 * 20}")
    private int calculationResult;
    
    // 系統(tǒng)屬性
    @Value("#{systemProperties['java.home']}")
    private String javaHome;
    
    // 隨機值
    @Value("#{T(java.lang.Math).random() * 100.0}")
    private double randomNumber;
    
    // 調(diào)用其他 Bean 的方法
    @Value("#{databaseConfig.databaseUrl}")
    private String dbUrlFromBean;
    
    // 三元操作符
    @Value("#{systemProperties['app.dev'] == 'true' ? 'dev' : 'prod'}")
    private String environment;
}

注入集合類型

@Component
public class CollectionConfig {
    
    // 注入列表(逗號分隔)
    @Value("${app.roles:admin,user,guest}")
    private List<String> roles;
    
    // 注入集合
    @Value("${app.permissions:read,write,execute}")
    private Set<String> permissions;
    
    // 注入映射(需要特殊格式)
    @Value("#{${app.settings}}")
    private Map<String, String> settings;
}

條件化注入

@Component
public class ConditionalConfig {
    
    // 根據(jù)系統(tǒng)屬性決定是否啟用某個功能
    @Value("#{systemProperties['feature.enabled'] ?: false}")
    private boolean featureEnabled;
    
    // 根據(jù)配置文件決定超時時間
    @Value("#{${app.timeout:30} * 1000}")
    private long timeoutInMillis;
}

最佳實踐

  1. 合理使用默認值:為配置屬性提供合理的默認值,增強應用的健壯性,避免因缺少配置導致應用啟動失敗。

  2. 類型安全:確保配置值能夠正確轉(zhuǎn)換為目標類型,避免類型轉(zhuǎn)換異常。

  3. 配置分組:對于相關(guān)的配置項,考慮使用配置類進行分組管理。

  4. 避免硬編碼:不要在 @Value 注解中硬編碼敏感信息,應該使用配置文件或環(huán)境變量。

// 推薦的配置管理方式
@Component
@PropertySource("classpath:app.properties")
public class ApplicationConfig {
    
    @Value("${app.name:DefaultApp}")
    private String appName;
    
    @Value("${app.version:1.0.0}")
    private String appVersion;
    
    @Value("${app.debug:false}")
    private boolean debugMode;
    
    @Value("${app.max-connections:100}")
    private int maxConnections;
    
    // 對于復雜配置,建議使用 @ConfigurationProperties
    @Value("${app.whitelist:127.0.0.1,localhost}")
    private List<String> whitelist;
    
    // 提供 getter 方法供其他組件使用
    public String getAppName() {
        return appName;
    }
    
    public String getAppVersion() {
        return appVersion;
    }
    
    public boolean isDebugMode() {
        return debugMode;
    }
    
    public int getMaxConnections() {
        return maxConnections;
    }
    
    public List<String> getWhitelist() {
        return whitelist;
    }
}

與其他注解的配合使用

與 @PropertySource 配合

@Configuration
@PropertySource("classpath:database.properties")
public class DatabaseConfiguration {
    
    @Value("${database.driver:com.mysql.cj.jdbc.Driver}")
    private String driverClassName;
    
    @Value("${database.url}")
    private String url;
    
    @Value("${database.username}")
    private String username;
    
    @Value("${database.password}")
    private String password;
    
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setJdbcUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

在構(gòu)造函數(shù)中使用

@Component
public class EmailService {

    private final String smtpHost;
    private final int smtpPort;
    private final boolean useSSL;

    // 構(gòu)造函數(shù)注入配置值
    public EmailService(
            @Value("${mail.smtp.host:localhost}") String smtpHost,
            @Value("${mail.smtp.port:25}") int smtpPort,
            @Value("${mail.smtp.ssl:false}") boolean useSSL) {
        this.smtpHost = smtpHost;
        this.smtpPort = smtpPort;
        this.useSSL = useSSL;
    }

    // 郵件發(fā)送邏輯
    public void sendEmail(String to, String subject, String content) {
        // 實現(xiàn)郵件發(fā)送邏輯
    }
}

通過合理使用 @Value 注解,可以輕松地將外部配置注入到 Spring 應用中,實現(xiàn)配置與代碼的分離,提高應用的靈活性和可維護性。

總結(jié)

到此這篇關(guān)于springboot常見的一些相關(guān)注解總結(jié)的文章就介紹到這了,更多相關(guān)springboot相關(guān)注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java緩存Map設置過期時間實現(xiàn)解析

    Java緩存Map設置過期時間實現(xiàn)解析

    這篇文章主要介紹了Java緩存Map設置過期時間實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • java面試中經(jīng)常會問到的mysql問題有哪些總結(jié)(基礎版)

    java面試中經(jīng)常會問到的mysql問題有哪些總結(jié)(基礎版)

    MySQL作為常見的數(shù)據(jù)庫技術(shù),其掌握程度往往是評估候選人綜合能力的重要組成部分,下面這篇文章主要介紹了java面試中經(jīng)常會問到的mysql問題有哪些的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-10-10
  • SpringMVC高級開發(fā)功能實現(xiàn)過程解析

    SpringMVC高級開發(fā)功能實現(xiàn)過程解析

    這篇文章主要介紹了SpringMVC高級開發(fā)功能實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • Java使用POI庫快速生成Word文檔的方法詳解

    Java使用POI庫快速生成Word文檔的方法詳解

    這篇文章主要介紹了Java使用POI庫快速生成Word文檔的方法,Java POI庫是一個開源的Java庫,能夠用來讀寫Microsoft Office格式的文件,尤其在處理文檔和電子表格方面功能強大,需要的朋友可以參考下
    2025-10-10
  • SpringBoot中的雙數(shù)據(jù)源配置過程

    SpringBoot中的雙數(shù)據(jù)源配置過程

    文章介紹了如何配置Oracle和PostgreSQL數(shù)據(jù)源,并使用JdbcTemplate進行數(shù)據(jù)庫操作,重點包括數(shù)據(jù)源配置、JdbcTemplate配置以及不同數(shù)據(jù)源的包路徑設置
    2026-01-01
  • Spring?Validation實現(xiàn)數(shù)據(jù)校驗的示例

    Spring?Validation實現(xiàn)數(shù)據(jù)校驗的示例

    Spring?Validation其實就是對Hibernate?Validator進一步的封裝,方便在Spring中使用,這篇文章主要介紹了Spring?Validation實現(xiàn)數(shù)據(jù)校驗的示例,需要的朋友可以參考下
    2023-03-03
  • java線性表排序示例分享

    java線性表排序示例分享

    這篇文章主要介紹了java線性表排序示例,需要的朋友可以參考下
    2014-03-03
  • Spring Data中domain模塊的使用

    Spring Data中domain模塊的使用

    Spring Data是一個流行的數(shù)據(jù)訪問框架,本文主要介紹了Spring Data中domain模塊的使用,并展示如何使用它來優(yōu)化我們的數(shù)據(jù)訪問層,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • java isPalindrome方法在密碼驗證中的應用

    java isPalindrome方法在密碼驗證中的應用

    這篇文章主要為大家介紹了java isPalindrome方法在密碼驗證中的簡單應用技巧,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀

    AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀

    這篇文章主要為大家介紹了AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12

最新評論

墨竹工卡县| 山东省| 汶川县| 宝山区| 如皋市| 长垣县| 五指山市| 罗城| 鹤壁市| 视频| 屯留县| 襄汾县| 酒泉市| 吉木萨尔县| 紫金县| 柘城县| 临海市| 家居| 永清县| 塘沽区| 太湖县| 方山县| 龙岩市| 福海县| 东安县| 台湾省| 东海县| 龙江县| 济阳县| 桑日县| 柏乡县| 康平县| 青岛市| 湘乡市| 蕉岭县| 梓潼县| 弥渡县| 福安市| 榕江县| 开鲁县| 香港|