Spring 功能強大但體積龐大(動輒 40MB+ JAR),且原始碼複雜難讀。本文展示一個極簡 IoC 容器實現,核心特性:
Config 物件)@Component、@Autowired、包掃描參考 Spring Bean 生命週期:實例化 → 屬性填充 → 初始化 → 銷毀。通過 BeanDefinition 保存元資料,BeanFactory 負責創建與依賴注入,ApplicationContext 提供高階功能(事件、國際化等)。
// 程式化配置替代 XML
public class Config {
private final Map<String, BeanDefinition> registry = new HashMap<>();
public Config scan(String basePackage) { /* 掃描 @Component */ return this; }
public Config bean(String name, Class<?> clazz) { /* 手動註冊 */ return this; }
public Config property(String beanName, String prop, Object value) { /* 屬性注入 */ return this; }
}
// Bean 定義元資料
class BeanDefinition {
String name; Class<?> type; String scope = "singleton";
boolean lazyInit; Map<String, Object> properties;
List<String> dependsOn; // 依賴順序
}
// 核心工廠
public class SimpleIoCContainer implements BeanFactory {
private final Map<String, BeanDefinition> definitions = new ConcurrentHashMap<>();
private final Map<String, Object> singletons = new ConcurrentHashMap<>();
public Object getBean(String name) { /* 實例化邏輯 */ }
private Object createBean(BeanDefinition bd) { /* 反射創建 + 屬性填充 + 初始化 */ }
private void populateBean(Object bean, BeanDefinition bd) { /* @Autowired 處理 */ }
}
// 測試代碼 (test.mvc.App.java)
public class App {
public static void main(String[] args) {
Config config = new Config()
.scan("com.example.service") // 掃描註解
.bean("dataSource", HikariDataSource.class)
.property("dataSource", "jdbcUrl", "jdbc:mysql://localhost:3306/db")
.property("dataSource", "username", "root");
SimpleIoCContainer container = new SimpleIoCContainer(config);
UserService service = container.getBean("userService");
service.doBusiness();
}
}
src/ ├── main/java/ │ ├── ioc/ # 核心容器實現 │ │ ├── Config.java │ │ ├── BeanDefinition.java │ │ ├── SimpleIoCContainer.java │ │ └── annotation/ # @Component, @Autowired 等 │ └── test/mvc/App.java
專案地址:https://github.com/y2k0103/ioc
無 Maven,直接導入 Eclipse 作為 Dynamic Web Project 即可運行。