在 Spring 框架中,控制層(Controller)、業務層(Service)?和?持久層(Repository/Mapper)?是分層架構的核心組成部分,職責分離明確,通過依賴注入(DI)協作。
1. 各層職責
(1) 控制層(Controller)
-
作用:處理?HTTP 請求和響應,是前后端交互的入口。
-
職責:
-
接收請求參數(如?
@RequestParam
、@RequestBody
)。 -
調用?業務層?處理邏輯。
-
返回 JSON 數據或視圖(如?
@ResponseBody
)。
-
-
核心注解:
-
@Controller
(返回視圖)或?@RestController
(純 API,返回 JSON)。
-
(2) 業務層(Service)
-
作用:處理?核心業務邏輯(如訂單計算、權限校驗)。
-
職責:
-
組合多個持久層操作(如事務管理)。
-
處理業務規則(如數據校驗、流程控制)。
-
調用?持久層?操作數據庫。
-
-
核心注解:
-
@Service
(標識業務組件)。 -
@Transactional
(管理事務)。
-
(3) 持久層(Repository/Mapper)
-
作用:直接與?數據庫交互,執行 CRUD 操作。
-
職責:
-
定義數據庫操作方法(如 SQL 或 ORM 映射)。
-
屏蔽數據庫細節(如 MySQL 或 MongoDB 差異)。
-
-
核心注解:
-
JPA:
@Repository
(接口繼承?JpaRepository
)。 -
MyBatis:
@Mapper
(接口 + XML/SQL 映射)。
-
2. 各層協作關系
(1) 調用流程
HTTP請求 → Controller → Service → Repository → 數據庫↑返回響應 ↑業務邏輯 ↑SQL執行
-
Controller?接收請求參數,校驗格式。
-
Service?處理業務邏輯(如訂單總價計算),調用 Repository 讀寫數據。
-
Repository?執行 SQL 或通過 ORM 操作數據庫,返回結果給 Service。
-
Service?處理完成后,返回數據給 Controller。
-
Controller?封裝響應(如 JSON),返回給前端。
(2) 依賴關系
-
單向依賴:
Controller → Service → Repository
-
上層依賴下層,下層不感知上層(如 Repository 不依賴 Service)。
-
通過?
@Autowired
?實現依賴注入。
-
3. 分層優勢
優勢 | 說明 |
---|---|
職責分離 | 各層專注單一職責(如 Controller 處理請求,Service 處理業務)。 |
代碼復用 | 多個 Controller 可共用同一個 Service(如訂單和支付模塊共用用戶服務)。 |
易于維護 | 修改數據庫邏輯只需調整 Repository,不影響 Service 和 Controller。 |
事務管理 | 事務注解(@Transactional )通常放在 Service 層,確保業務操作原子性。 |
測試友好 | 可單獨測試 Service 邏輯,Mock 數據庫操作(如使用 Mockito)。 |
4. 實際開發中的常見問題
(1) 能不能跳過 Service,直接 Controller 調用 Repository?
-
不推薦!會導致:
-
業務邏輯散落在 Controller 中,難以復用。
-
事務管理困難(如多個 Repository 操作無法統一回滾)。
-
(2) Service 層為什么需要接口?
-
接口的作用:
-
實現類可替換(如切換緩存策略)。
-
便于 AOP 代理(如事務管理、日志切面)。
public interface UserService { // 接口User getUserById(Long id); }@Service public class UserServiceImpl implements UserService { // 實現類// 具體邏輯 }
-
? ? (3) 實體類(Entity)放在哪一層?
-
通常獨立為領域模型層:
com.example.project ├── controller ├── service ├── repository └── entity // 實體類(User、Order)
-
所有層共享實體類,但?避免將實體直接暴露給前端(建議用 DTO 轉換)。
-
5. 總結
-
Controller:處理 HTTP 交互,參數校驗,調用 Service。
-
Service:核心業務邏輯,事務管理,調用 Repository。
-
Repository:數據庫操作,屏蔽 SQL 細節。