IoC容器深度解析:从手动new到自动装配的演进

引子:一个UserService的五种创建方式 假设你要创建一个UserService,它依赖UserRepository,而UserRepository又依赖DataSource。 这个看似简单的三层依赖,在不同的阶段有完全不同的创建方式: // 方式1:手动new(最原始) UserService userService = new UserService( new UserRepository( new DataSource("jdbc:mysql://localhost:3306/db", "root", "123456") ) ); // 方式2:工厂模式(稍好一点) UserService userService = UserServiceFactory.create(); // 方式3:依赖注入(手动装配) UserService userService = new UserService(); userService.setUserRepository(new UserRepository()); // 方式4:IoC容器(自动装配) ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserService userService = context.getBean(UserService.class); // 方式5:Spring Boot(零配置) @Autowired private UserService userService; // 自动注入 从方式1到方式5,到底发生了什么? 今天我们将通过5个渐进式场景,深度剖析IoC容器的演进逻辑,并亲手实现一个200行的简化版IoC容器。 一、场景0:手动new的噩梦(无容器) 1.1 三层依赖的手动创建 /** * 场景0:完全手动管理依赖 * 问题:硬编码、强耦合、难以测试 */ public class ManualDependencyDemo { public static void main(String[] args) { // 第1层:创建DataSource DataSource dataSource = new DataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setMaxPoolSize(10); // 第2层:创建UserRepository(依赖DataSource) UserRepository userRepository = new UserRepository(); userRepository.setDataSource(dataSource); // 第3层:创建UserService(依赖UserRepository) UserService userService = new UserService(); userService.setUserRepository(userRepository); // 使用 User user = userService.getUser(1L); System.out.println(user); } } /** * DataSource - 数据源 */ class DataSource { private String url; private String username; private String password; private int maxPoolSize; // getter/setter省略 } /** * UserRepository - 数据访问层 */ class UserRepository { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public User findById(Long id) { // 使用dataSource查询数据库 System.out.println("查询数据库,dataSource: " + dataSource); return new User(id, "张三"); } } /** * UserService - 业务逻辑层 */ class UserService { private UserRepository userRepository; public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } public User getUser(Long id) { return userRepository.findById(id); } } /** * User - 实体类 */ class User { private Long id; private String name; public User(Long id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "User{id=" + id + ", name='" + name + "'}"; } } 1.2 核心问题分析 问题清单: ...

2025-11-03 · maneng

如约数科科技工作室

浙ICP备2025203501号

👀 本站总访问量 ...| 👤 访客数 ...| 📅 今日访问 ...