Spring Boot3 IOC 項目地址
https://gitee.com/supervol/loong-springboot-study
(記得給個start,感謝)
IOC 概述
????????在 Spring Boot 3 中,IOC(Inversion of Control,控制反轉)是核心思想之一,它徹底改變了傳統 Java 開發中對象創建和依賴管理的方式,極大地降低了代碼耦合度,提升了系統的可維護性和擴展性。
IOC 核心概念
????????IOC 的本質是將對象的創建權、依賴關系的管理交給 Spring 容器,而非由開發者在代碼中手動 new 對象或維護依賴。這種 "反轉" 體現在:
- 傳統開發:開發者主動控制對象創建(如
UserService service = new UserService()
)和依賴注入(如service.setDao(new UserDao())
)。 - IOC 模式:Spring 容器負責創建對象(Bean),并根據配置自動將依賴對象 "注入" 到目標對象中,開發者只需聲明 "需要什么",無需關心 "如何獲取"。
IOC 與 DI 的關系
????????DI(Dependency Injection,依賴注入)是 IOC 的具體實現方式。
- IOC 是思想:強調 "反轉控制"(將對象管理權交給容器)。
- DI 是手段:容器通過構造器、setter 方法等方式,將依賴對象 "注入" 到目標對象中,完成依賴關系綁定。
IOC 示例
????????請參考項目地址中 springboot-ioc/springboot-ioc-demo 模塊代碼。
IOC 使用
????????Spring Boot 3 基于 Spring Framework 6,簡化了 IOC 容器的配置(無需 XML,全注解驅動),核心步驟如下:
定義 Bean
????????讓容器管理對象,Spring 通過注解識別需要管理的對象(Bean),常用注解:
@Component
:通用注解,標識一個類為 Spring 管理的 Bean(適用于普通組件)。@Service
:標注業務邏輯層(Service)的 Bean(語義化注解,本質是@Component
)。@Controller
:標注控制層(MVC 中的 Controller)的 Bean。@Repository
:標注數據訪問層(DAO)的 Bean,還會自動處理數據庫操作異常。
?示例:定義 Service 層 Bean
// 業務邏輯層,@Service標識為Spring管理的Bean
@Service
public class UserService {// 后續通過DI注入依賴private final UserDao userDao;// 構造器注入(推薦)public UserService(UserDao userDao) {this.userDao = userDao;}public String getUserInfo() {return userDao.queryUser();}
}
示例:定義 DAO 層 Bean
// 數據訪問層,@Repository標識為Spring管理的Bean
@Repository
public class UserDao {public String queryUser() {return "用戶信息:張三";}
}
依賴注入(DI)
????????容器自動注入依賴,Spring 提供多種注入方式,推薦構造器注入(更符合單一職責,且避免空指針問題)。
(1)構造器注入(推薦)
通過類的構造方法,容器自動傳入依賴的 Bean(如上面UserService
中注入UserDao
)。
(2)Setter 方法注入
通過 setter 方法注入依賴,需配合@Autowired
注解:
@Service
public class UserService {private UserDao userDao;// Setter注入@Autowiredpublic void setUserDao(UserDao userDao) {this.userDao = userDao;}
}
(3)字段注入(不推薦)
直接在字段上使用@Autowired
注入,缺點是無法通過構造器保證依賴非空,且不利于單元測試:
@Service
public class UserService {// 字段注入(不推薦)@Autowiredprivate UserDao userDao;
}
啟動容器并使用 Bean
????????Spring Boot 通過@SpringBootApplication
注解啟動容器,該注解包含:
@ComponentScan
:自動掃描當前包及子包下的@Component
(含@Service
、@Controller
等)注解類,將其注冊為 Bean。
示例:啟動類與使用 Bean
// 啟動類,@SpringBootApplication標識Spring Boot應用入口
@SpringBootApplication
public class IocDemoApplication {public static void main(String[] args) {// 啟動Spring容器,返回ApplicationContext(容器上下文)ApplicationContext context = SpringApplication.run(IocDemoApplication.class, args);// 從容器中獲取UserService BeanUserService userService = context.getBean(UserService.class);// 調用Bean的方法(依賴已由容器自動注入)System.out.println(userService.getUserInfo()); // 輸出:用戶信息:張三}
}
自定義 Bean
????????非 @Component 注解類,如果需要將第三方類(如RedisTemplate
)或未加@Component
的類注冊為 Bean,可通過@Configuration
+@Bean
實現:
// 配置類,@Configuration標識為配置類
@Configuration
public class CustomConfig {// @Bean:將方法返回值注冊為Spring容器中的Bean,默認名稱為方法名@Beanpublic RedisUtil redisUtil() {return new RedisUtil(); // 假設RedisUtil是第三方工具類}
}// 使用自定義Bean
@Service
public class OrderService {private final RedisUtil redisUtil;// 注入自定義的RedisUtil Beanpublic OrderService(RedisUtil redisUtil) {this.redisUtil = redisUtil;}
}
Bean 的作用域
????????默認情況下,Spring 容器中的 Bean 是單例(singleton)(整個容器中只有一個實例)。可通過@Scope
指定其他作用域:
@Scope("prototype")
:多例,每次獲取 Bean 時創建新實例。@Scope("request")
:Web 環境中,每個請求對應一個實例。@Scope("session")
:Web 環境中,每個會話對應一個實例。
示例:多例 Bean
@Service
@Scope("prototype") // 多例模式
public class CartService {// ...
}
IOC 的優勢
- 解耦:對象創建與依賴管理交給容器,避免硬編碼依賴(如
new UserService(new UserDao())
)。 - 可維護性:集中管理 Bean 的生命周期和依賴,修改依賴只需調整配置。
- 可測試性:便于替換依賴(如測試時用 Mock 對象替換真實 DAO)。
- 靈活性:通過作用域、懶加載等配置,靈活控制 Bean 的創建時機和生命周期。
總結
????????Spring Boot 3 的 IOC 通過注解驅動簡化了 Bean 的定義和依賴管理,核心是 "將控制權交給容器"。實際開發中,推薦使用@Service
、@Repository
等語義化注解定義 Bean,通過構造器注入管理依賴,配合@Configuration
+@Bean
處理自定義 Bean,充分發揮 IOC 的解耦優勢。