?1.?@Autowired
?字段注入(不推薦)?
@Service
public class UserService {@Autowired // 直接在字段上注入private UserRepository userRepository;
}
??原理??:Spring 啟動時掃描所有?@Component
、@Service
?等注解的類,發現?@Autowired
?字段后,自動從容器中查找匹配的 Bean 并注入。
2. Setter 注入?(不推薦)
@Service
public class UserService {private UserRepository userRepository;@Autowired // 在 setter 方法上注入public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}
}
??原理??:Spring 掃描到?@Autowired
?標記的 Setter 方法后,自動調用該方法注入依賴。
3. 構造函數注入?(推薦)
3.1 手動構造函數
@Service
public class UserService {private final UserRepository userRepository; // final 確保不可變// 手動編寫構造函數public UserService(UserRepository userRepository) {this.userRepository = userRepository;}
}
??原理?:?
- Spring 通過反射調用構造函數,自動注入依賴。
- ??Spring 4.3+ 后,如果類只有一個構造函數,可以省略?
@Autowired
??(Spring 會自動識別)。
3.2?構造函數 +?@RequiredArgsConstructor
(Lombok)(強烈推薦)
@Service
@RequiredArgsConstructor // Lombok 自動生成構造函數
public class UserService {private final UserRepository userRepository; // final 確保不可變
}
原理?:?
- Lombok 的?
@RequiredArgsConstructor
?會自動生成一個包含所有?final
?字段和?@NonNull
?字段的構造函數。 - Spring 會自動調用這個構造函數注入依賴(無需?
@Autowired
)。
總結
特性 | @Autowired ?字段注入 | Setter 注入 | 構造函數注入 | 構造函數 +?@RequiredArgsConstructor |
---|---|---|---|---|
??代碼簡潔性?? | ????(最簡潔) | ??? | ??(需手動寫構造函數) | ????(Lombok 自動生成) |
??可讀性?? | ?(依賴關系隱藏) | ??(setter 分散) | ????(構造函數明確) | ????(和手動構造函數一樣清晰) |
??可測試性?? | ?(難以測試) | ??(需手動注入) | ????(直接傳入 mock) | ????(和手動構造函數一樣) |
??不可變性(final)?? | ?(不支持) | ?(不支持) | ????(支持) | ????(支持) |
??Spring 推薦程度?? | ?(不推薦) | ?(僅可選依賴) | ????(推薦) | ????(推薦) |
??是否需要 Lombok?? | ? | ? | ? | ????(依賴 Lombok) |