Java常用注解擴(kuò)展對(duì)比舉例詳解
一、@Controller 與 @RestController 對(duì)比
| 對(duì)比維度 | @Controller | @RestController |
|---|---|---|
| 定義 | Spring MVC 的基礎(chǔ)控制器注解 | @Controller + @ResponseBody 的組合注解 |
| 返回值處理 | 返回視圖名稱(需配合視圖解析器) | 直接返回JSON/XML數(shù)據(jù)(自動(dòng)添加 @ResponseBody) |
| 適用場(chǎng)景 | 傳統(tǒng)MVC架構(gòu)(如JSP/Thymeleaf頁面渲染) | RESTful API開發(fā)(前后端分離場(chǎng)景) |
| HTTP響應(yīng)頭 | Content-Type: text/html(默認(rèn)) | Content-Type: application/json(默認(rèn)) |
| 代碼示例 | ```java | ```java |
| @Controller | @RestController | |
| public class WebCtrl { | public class ApiCtrl { | |
| @GetMapping(“/page”) | @GetMapping(“/data”) | |
| public String page() { | public User data() { | |
| return “index”; // 返回視圖名 | return userService.findUser(); // 自動(dòng)轉(zhuǎn)JSON | |
| } | } | |
| } | } |
二、使用 @Data 與 不使用 @Data 對(duì)比
| 對(duì)比維度 | 使用 @Data | 不使用 @Data |
|---|---|---|
| 代碼量 | 自動(dòng)生成以下方法: - 所有字段的getter/setter - toString()- equals()/hashCode() | 需手動(dòng)編寫所有方法 |
| 維護(hù)性 | 字段增減時(shí)無需修改方法 | 字段變更需同步修改相關(guān)方法 |
| 繼承關(guān)系處理 | 需顯式添加 @EqualsAndHashCode(callSuper=true) 包含父類字段 | 手動(dòng)編寫時(shí)可直接控制是否包含父類字段 |
| 框架兼容性 | 依賴Lombok插件(需IDE支持) | 無額外依賴 |
| 代碼示例 | ```java | ```java |
| @Data | public class User { | |
| public class User { | private Long id; | |
| private Long id; | private String name; | |
| private String name; | ||
| // 自動(dòng)生成所有方法 | // 手動(dòng)編寫getter/setter | |
| } | public Long getId() { return id; } | |
| public void setId(Long id) { this.id = id; } | ||
| // …其他方法 | ||
| } |
注意事項(xiàng):
- 使用
@Data時(shí),若類有繼承關(guān)系,需添加@EqualsAndHashCode(callSuper=true) - 某些場(chǎng)景(如JPA實(shí)體類)需顯式定義無參構(gòu)造器(通過
@NoArgsConstructor)
三、使用 @TableName 與 不使用 @TableName 對(duì)比
| 對(duì)比維度 | 使用 @TableName | 不使用 @TableName |
|---|---|---|
| 表名映射規(guī)則 | 顯式指定數(shù)據(jù)庫表名(如 @TableName("sys_user")) | 按MyBatis-Plus默認(rèn)規(guī)則映射: 類名駝峰轉(zhuǎn)下劃線(如 SysUser → sys_user) |
| 適用場(chǎng)景 | 1. 表名含特殊字符(如 user-info)2. 類名與表名無對(duì)應(yīng)關(guān)系 | 類名與表名嚴(yán)格遵循駝峰轉(zhuǎn)下劃線規(guī)則 |
| 全局配置覆蓋 | 優(yōu)先級(jí)高于全局配置 | 可通過配置文件統(tǒng)一設(shè)置表名前綴:mybatis-plus.global-config.db-config.table-prefix=sys_ |
| 代碼示例 | ```java | ```java |
| @Data | @Data | |
| @TableName(“sys_user”) // 顯式指定表名 | public class SysUser { // 默認(rèn)映射為 sys_user | |
| public class User { | private Long id; | |
| private Long id; | } | |
| } |
注意事項(xiàng):
- 表名包含SQL關(guān)鍵字時(shí)需轉(zhuǎn)義:
@TableName("order") - 分表場(chǎng)景可通過動(dòng)態(tài)表名處理器(
TableNameHandler)實(shí)現(xiàn)
四、依賴注入注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Autowired vs @Resource | - @Autowired(Spring)按類型注入- @Resource(JSR-250)按名稱注入 | 明確指定Bean名稱時(shí)用@Resource,優(yōu)先使用構(gòu)造器注入時(shí)用@Autowired |
| @Primary vs @Qualifier | - @Primary標(biāo)記首選Bean- @Qualifier指定具體Bean名稱 | 存在多個(gè)相同類型Bean時(shí),優(yōu)先使用@Primary,需精確控制時(shí)用@Qualifier |
代碼示例:
// @Autowired + @Qualifier
@Autowired
@Qualifier("mysqlDataSource")
private DataSource dataSource;
// @Resource
@Resource(name = "oracleDataSource")
private DataSource dataSource;
五、Spring MVC 參數(shù)綁定注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @RequestParam vs @PathVariable | - @RequestParam獲取URL參數(shù)- @PathVariable獲取URI模板變量 | RESTful風(fēng)格URL用@PathVariable,傳統(tǒng)表單參數(shù)用@RequestParam |
| @ModelAttribute vs @RequestBody | - @ModelAttribute綁定Form表單數(shù)據(jù)- @RequestBody綁定JSON請(qǐng)求體 | 表單提交用@ModelAttribute,API接口傳輸復(fù)雜對(duì)象用@RequestBody |
代碼示例:
// PathVariable
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) { ... }
// RequestBody
@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody UserDTO userDTO) { ... }
六、JPA/Hibernate 映射注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Entity vs @Table | - @Entity聲明JPA實(shí)體類- @Table指定數(shù)據(jù)庫表名 | 類名與表名不一致時(shí)使用@Table |
| @Column vs @Transient | - @Column映射數(shù)據(jù)庫列- @Transient標(biāo)記非持久化字段 | 字段需要特殊列名或類型時(shí)用@Column,臨時(shí)計(jì)算字段用@Transient |
| @OneToMany vs @ManyToOne | - 定義一對(duì)多/多對(duì)一關(guān)系 | 根據(jù)業(yè)務(wù)關(guān)系方向選擇(部門-員工:部門用@OneToMany,員工用@ManyToOne) |
代碼示例:
@Entity
@Table(name = "departments")
public class Department {
@OneToMany(mappedBy = "department")
private List<Employee> employees;
}
@Entity
public class Employee {
@ManyToOne
@JoinColumn(name = "dept_id")
private Department department;
}
七、Spring Boot 配置注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Value vs @ConfigurationProperties | - @Value注入單個(gè)屬性- @ConfigurationProperties批量綁定屬性 | 簡(jiǎn)單配置用@Value,復(fù)雜配置對(duì)象用@ConfigurationProperties |
| @Profile vs @Conditional | - @Profile按環(huán)境激活配置- @Conditional按條件創(chuàng)建Bean | 多環(huán)境配置用@Profile,動(dòng)態(tài)裝配邏輯用@Conditional |
配置示例:
# application.yml
app:
security:
enabled: true
timeout: 300
代碼實(shí)現(xiàn):
@Configuration
@ConfigurationProperties(prefix = "app.security")
public class SecurityConfig {
private boolean enabled;
private int timeout;
// getters/setters
}
八、Lombok 注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Data vs @Value | - @Data生成可變對(duì)象- @Value生成不可變對(duì)象(final字段) | 需要修改字段值時(shí)用@Data,只讀數(shù)據(jù)傳輸對(duì)象用@Value |
| @Builder vs @AllArgsConstructor | - @Builder支持鏈?zhǔn)綐?gòu)建- @AllArgsConstructor生成全參構(gòu)造器 | 復(fù)雜對(duì)象構(gòu)建用@Builder,依賴注入全參構(gòu)造用@AllArgsConstructor |
代碼示例:
@Value
@Builder
public class ImmutablePoint {
private final int x;
private final int y;
}
// 使用
ImmutablePoint point = ImmutablePoint.builder().x(10).y(20).build();
九、事務(wù)管理注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Transactional vs @Modifying | - @Transactional聲明事務(wù)邊界- @Modifying標(biāo)記DML操作 | 服務(wù)層方法用@Transactional,JPA更新查詢用@Modifying |
代碼示例:
@Service
public class UserService {
@Transactional
public void updateUser(User user) {
userRepository.save(user);
}
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Query("UPDATE User u SET u.name = ?1 WHERE u.id = ?2")
int updateNameById(String name, Long id);
}
十、測(cè)試相關(guān)注解對(duì)比
| 注解對(duì) | 核心區(qū)別 | 使用場(chǎng)景 |
|---|---|---|
| @Mock vs @MockBean | - @Mock(Mockito)創(chuàng)建模擬對(duì)象- @MockBean(Spring Boot Test)替換Spring容器中的Bean | 單元測(cè)試用@Mock,集成測(cè)試用@MockBean |
| @SpringBootTest vs @WebMvcTest | - @SpringBootTest加載完整上下文- @WebMvcTest僅加載Web層組件 | 全集成測(cè)試用@SpringBootTest,控制層隔離測(cè)試用@WebMvcTest |
測(cè)試示例:
// 全集成測(cè)試
@SpringBootTest
class UserServiceIntegrationTest {
@Autowired
private UserService userService;
}
// 控制層測(cè)試
@WebMvcTest(UserController.class)
class UserControllerTest {
@MockBean
private UserService userService;
@Autowired
private MockMvc mockMvc;
}
綜合對(duì)比總結(jié)表
| 功能場(chǎng)景 | 推薦注解組合 | 典型應(yīng)用 |
|---|---|---|
| REST API開發(fā) | @RestController + @RequestBody + @Valid | 前后端分離接口開發(fā) |
| JPA實(shí)體映射 | @Entity + @Table + @Column + @OneToMany | 數(shù)據(jù)庫表結(jié)構(gòu)映射 |
| 配置管理 | @ConfigurationProperties + @Profile | 多環(huán)境配置切換 |
| 測(cè)試覆蓋 | @SpringBootTest + @MockBean + @DataJpaTest(按需選擇) | 分層測(cè)試策略 |
| 依賴注入 | 構(gòu)造器注入優(yōu)先,@Autowired + @Qualifier | 避免循環(huán)依賴 |
最佳實(shí)踐建議
分層使用嚴(yán)格遵循Controller→Service→Repository分層架構(gòu),避免跨層注解混用。
注解最小化
- 優(yōu)先使用框架提供的組合注解(如
@RestController代替@Controller+@ResponseBody) - 避免重復(fù)注解(如同時(shí)使用
@Component和@Service)
- 優(yōu)先使用框架提供的組合注解(如
Lombok規(guī)范
- 實(shí)體類統(tǒng)一使用
@Data+@Builder - 禁用無約束的
@AllArgsConstructor
- 實(shí)體類統(tǒng)一使用
事務(wù)控制
- Service層統(tǒng)一聲明
@Transactional(readOnly = true) - 寫操作顯式指定
@Transactional(rollbackFor = Exception.class)
- Service層統(tǒng)一聲明
測(cè)試隔離
- 單元測(cè)試使用Mockito + JUnit5
- 集成測(cè)試按需選擇
@WebMvcTest或@DataJpaTest
通過系統(tǒng)化的注解對(duì)比與組合使用,可顯著提高代碼規(guī)范性和團(tuán)隊(duì)協(xié)作效率。建議結(jié)合SonarLint等代碼質(zhì)量管理工具,確保注解使用的合理性與一致性。
總結(jié)
到此這篇關(guān)于Java常用注解擴(kuò)展對(duì)比的文章就介紹到這了,更多相關(guān)Java常用注解擴(kuò)展內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring boot項(xiàng)目部署到云服務(wù)器小白教程詳解
這篇文章主要介紹了Spring boot項(xiàng)目部署到云服務(wù)器小白教程詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
Java使用CountDownLatch實(shí)現(xiàn)統(tǒng)計(jì)任務(wù)耗時(shí)
這篇文章主要為大家詳細(xì)介紹了Java如何使用CountDownLatch實(shí)現(xiàn)統(tǒng)計(jì)任務(wù)耗時(shí)的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-06-06
Java Spring數(shù)據(jù)單元配置過程解析
這篇文章主要介紹了Java Spring數(shù)據(jù)單元配置過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
Java Thread中start()和run()的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
start() : 它的作用是啟動(dòng)一個(gè)新線程,新線程會(huì)執(zhí)行相應(yīng)的run()方法。start()不能被重復(fù)調(diào)用。而run() : run()就和普通的成員方法一樣,可以被重復(fù)調(diào)用。下面通過示例代碼給大家介紹了Java Thread中start()和run()的區(qū)別,感興趣的朋友一起看看吧2017-05-05
String與Blob互轉(zhuǎn)和file文件與Blob互轉(zhuǎn)方式
這篇文章主要介紹了String與Blob互轉(zhuǎn)和file文件與Blob互轉(zhuǎn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
深入探討Spring Statemachine在Spring中實(shí)現(xiàn)狀態(tài)機(jī)的過程
本文深入探討了Spring Statemachine的核心概念、功能及應(yīng)用,包括狀態(tài)和轉(zhuǎn)換的結(jié)構(gòu)化定義、事件驅(qū)動(dòng)的狀態(tài)變遷、持久化支持以及集成Spring生態(tài)系統(tǒng),通過實(shí)例分析,展示了其在多個(gè)領(lǐng)域的實(shí)際應(yīng)用,并討論了如何自定義擴(kuò)展以滿足特定需求,感興趣的朋友一起看看吧2025-04-04
使用AbstractRoutingDataSource實(shí)現(xiàn)數(shù)據(jù)源動(dòng)態(tài)切換的實(shí)例
AbstractRoutingDataSource 是 Spring 框架提供的一個(gè)抽象類,用于實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源路由,這個(gè)類主要用于多數(shù)據(jù)源場(chǎng)景,其中可以根據(jù)不同的條件動(dòng)態(tài)地切換到不同的數(shù)據(jù)源,本文給大家介紹了如何使用AbstractRoutingDataSource實(shí)現(xiàn)數(shù)據(jù)源動(dòng)態(tài)切換,需要的朋友可以參考下2024-03-03

