Spring 核心: IOC 容器
IOC(Inversion of Control,控制反转)是 Spring 框架的核心思想,Spring 对它的实现通常被称作 DI(Dependency Injection,依赖注入)
为什么需要 IOC
Spring 需要 IOC 的根本原因是:将对象创建和依赖管理的控制权从业务代码中剥离,交给容器统一处理,从而实现解耦、可维护性、可测试性和灵活性。这种设计模式是 Spring 成为企业级开发事实标准的基础之一。
简单来说,IOC 让程序员从复杂的对象组装工作中解放出来,专注于业务逻辑的实现。

面向对象的软件设计,是由 X 个对象组成,且对象之间彼此合作来完成某个功能

IOC将对象的创建、依赖关系的管理和生命周期的控制从应用程序代码中解耦出来
IOC 容器的核心设计:依赖注入

依赖注入的三种主要方式
- 构造器注入:通过构造方法强制注入必需的依赖,确保对象在创建时就处于完整可用状态。
- Setter 注入:通过 setter 方法提供可选或可变的依赖。
- 字段注入:直接在字段上通过
@Autowired注入依赖,简化代码但隐藏依赖关系。
Spring IOC 容器使用的是什么数据结构来存储 Bean (Object)
Spring IOC 容器主要使用多种数据结构的组合来存储和管理 Bean,不同容器实现略有差异。
- 找到
BeanDefinitionRegistry,找到int getBeanDefinitionCount();方法的任意一个实现类,源码如下
java
@Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}怎么获取 bean
一、基础获取方式
1. ApplicationContext 直接获取
java
@Component
public class AppContextAware implements ApplicationContextAware {
private static ApplicationContext ctx = null;
public AppContextAware() {
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
AppContextAware.ctx = applicationContext;
}
public static ApplicationContext getInstance() {
return ctx;
}
// 静态方法获取Bean
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
public static Object getBean(String beanName) {
return context.getBean(beanName);
}
// 使用
UserService userService = AppContextAware.getBean(UserService.class);
}2. BeanFactory 获取
java
// 方式2:通过 BeanFactory(ApplicationContext的父接口)
ConfigurableListableBeanFactory beanFactory =
((ConfigurableApplicationContext) context).getBeanFactory();
// 获取Bean
UserService userService = beanFactory.getBean(UserService.class);
// 检查Bean是否存在
boolean exists = beanFactory.containsBean("userService");
// 获取Bean的类型
Class<?> type = beanFactory.getType("userService");二、自动注入方式(推荐)
1. 字段注入(Field Injection)
java
@Component
public class UserController {
// 直接注入到字段
@Autowired
private UserService userService;
// 使用 @Resource(JSR-250标准)
@Resource
private UserService userService;
// 指定具体Bean名称
@Autowired
@Qualifier("primaryUserService")
private UserService userService;
}2. 构造器注入(Constructor Injection) - Spring 推荐
java
@Component
public class UserController {
private final UserService userService;
private final EmailService emailService;
// Spring 4.3+ 自动注入,无需 @Autowired
public UserController(UserService userService, EmailService emailService) {
this.userService = userService;
this.emailService = emailService;
}
}
// 使用 Lombok 简化
@Component
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
private final EmailService emailService;
}3. Setter 注入(Setter Injection)
java
@Component
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
// 可选依赖
@Autowired(required = false)
public void setOptionalService(OptionalService service) {
// 可能为 null
}
}
剑鸣秋朔