核心概念

IOC(Inversion of Control,控制反转) 是Spring框架的核心思想之一,指的是将对象创建和对象间依赖关系的管理权从应用程序代码转移到Spring容器。

传统开发模式下,对象的创建和依赖关系由程序主动控制;而在IOC模式下,这些职责被”反转”交给了Spring容器来管理,开发者只需声明依赖关系即可。

依赖注入(DI,Dependency Injection) 是IOC的具体实现方式,Spring通过DI将依赖对象注入到目标对象中。

工作原理与关键点

1. IOC容器的核心组件

  • BeanFactory:Spring IOC容器的基础接口,提供基本的Bean管理功能
  • ApplicationContext:BeanFactory的子接口,提供更多企业级功能(事件发布、国际化、AOP集成等)
// BeanFactory - 基础容器
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

// ApplicationContext - 增强容器(推荐)
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

2. 三种依赖注入方式

@Service
public class UserService {
    
    // 1. 构造器注入(推荐)
    private final UserRepository userRepository;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 2. Setter注入
    private EmailService emailService;
    
    @Autowired
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }
    
    // 3. 字段注入(不推荐,难以测试)
    @Autowired
    private LogService logService;
}

3. IOC容器的初始化流程

1. 加载配置(XML/注解/Java Config)
   ↓
2. 解析Bean定义,注册到BeanDefinitionRegistry
   ↓
3. 实例化Bean(调用构造器)
   ↓
4. 属性填充(依赖注入)
   ↓
5. 执行Aware接口回调(BeanNameAware、ApplicationContextAware等)
   ↓
6. 执行BeanPostProcessor的前置处理
   ↓
7. 执行初始化方法(@PostConstruct、InitializingBean、init-method)
   ↓
8. 执行BeanPostProcessor的后置处理(AOP代理在此创建)
   ↓
9. Bean就绪,可以使用

实际应用考量

1. 依赖注入方式选择

  • 构造器注入:适用于必需依赖,保证不可变性,推荐使用
  • Setter注入:适用于可选依赖,允许重新配置
  • 字段注入:代码简洁但不利于测试,不推荐

2. 容器选择

// 轻量级应用 - BeanFactory(懒加载)
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

// 企业级应用 - ApplicationContext(预加载,推荐)
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

3. 性能优化建议

  • 使用@Lazy延迟初始化非关键Bean
  • 合理设置Bean作用域(singleton vs prototype)
  • 避免循环依赖(使用构造器注入时会报错)

示例与总结

完整示例

// 配置类
@Configuration
@ComponentScan("com.example")
public class AppConfig {
    
    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        return dataSource;
    }
}

// Service层
@Service
public class OrderService {
    
    private final OrderRepository orderRepository;
    private final PaymentService paymentService;
    
    // 构造器注入
    @Autowired
    public OrderService(OrderRepository orderRepository, 
                       PaymentService paymentService) {
        this.orderRepository = orderRepository;
        this.paymentService = paymentService;
    }
    
    public void createOrder(Order order) {
        orderRepository.save(order);
        paymentService.processPayment(order);
    }
}

// 启动应用
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        
        OrderService orderService = context.getBean(OrderService.class);
        orderService.createOrder(new Order());
    }
}

面试总结

  1. IOC本质:控制权反转,由容器管理对象生命周期和依赖关系
  2. 优势:解耦、易测试、易维护、支持AOP
  3. 实现方式:通过依赖注入(构造器、Setter、字段)
  4. 核心容器:BeanFactory(基础)、ApplicationContext(增强)
  5. 最佳实践:优先使用构造器注入,避免循环依赖,合理配置作用域