一、Spring IOC实现原理
Spring IOC的核心实现类是org.springframework.beans.factory.BeanFactory和它的实现类org.springframework.context.ApplicationContext。最常用的是ClassPathXmlApplicationContext和AnnotationConfigApplicationContext。
主要流程:
- 资源定位:加载配置文件或注解,定位bean定义资源。
- 解析Bean定义:解析bean的配置信息,封装成
BeanDefinition对象。 - 注册Bean定义:将
BeanDefinition注册到BeanFactory的容器中。 - 实例化Bean:根据依赖关系实例化bean对象,处理依赖注入。
- 初始化Bean:执行初始化方法,如
@PostConstruct、InitializingBean等。 - 使用Bean:通过
getBean方法获取bean实例。
二、核心类介绍
- BeanFactory:最基础的IOC容器接口,定义了getBean等方法。
- ApplicationContext:扩展了BeanFactory,实现了更多功能,比如事件发布、国际化等。
- DefaultListableBeanFactory:BeanFactory的核心实现类,负责bean的注册和实例化。
- BeanDefinition:bean的元数据,描述bean的类型、作用域、依赖等信息。
- BeanWrapper:用于包装bean对象,便于属性注入。
三、简化版IOC容器源码实现
下面是一个简化版的IOC容器实现,仅支持单例bean和构造器注入:
import java.util.HashMap;
import java.util.Map;
// Bean定义
class BeanDefinition {
private Class<?> beanClass;
public BeanDefinition(Class<?> beanClass) {
this.beanClass = beanClass;
}
public Class<?> getBeanClass() {
return beanClass;
}
}
// 简易IOC容器
class SimpleIOC {
private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
private Map<String, Object> singletonBeans = new HashMap<>();
// 注册Bean定义
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
// 获取Bean实例
public Object getBean(String beanName) throws Exception {
Object bean = singletonBeans.get(beanName);
if (bean != null) {
return bean;
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) {
throw new Exception("No bean named " + beanName);
}
// 实例化bean(这里只支持无参构造器)
bean = beanDefinition.getBeanClass().getDeclaredConstructor().newInstance();
singletonBeans.put(beanName, bean);
return bean;
}
}
// 测试用Bean
class UserService {
public void sayHello() {
System.out.println("Hello, Spring IOC!");
}
}
// 测试
public class Main {
public static void main(String[] args) throws Exception {
SimpleIOC ioc = new SimpleIOC();
ioc.registerBeanDefinition("userService", new BeanDefinition(UserService.class));
UserService userService = (UserService) ioc.getBean("userService");
userService.sayHello();
}
}
四、Spring源码入口
如果你想深入学习Spring IOC源码,可以从以下类开始阅读:
DefaultListableBeanFactory.java(bean注册和实例化)AbstractApplicationContext.java(容器初始化流程)BeanDefinition.java(bean元数据)
五、源码深入讲解
1. BeanDefinition 注册与存储
Spring 在启动时,会将所有 bean 的配置信息(无论是 XML 还是注解)解析为 BeanDefinition 对象。BeanDefinition 记录了 bean 的类型、作用域、依赖、构造方法等元数据。
核心类:
BeanDefinitionDefaultListableBeanFactory(实现了 BeanDefinitionRegistry 接口)
源码片段:
// BeanDefinitionRegistry.java
public interface BeanDefinitionRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
// ... 其他方法
}
// DefaultListableBeanFactory.java
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
this.beanDefinitionMap.put(beanName, beanDefinition);
}
2. Bean 的实例化和依赖注入
Spring IOC 最核心的功能就是实例化 Bean 并自动进行依赖注入。Spring 支持多种注入方式(构造器、setter、字段注入等)。
核心方法:
AbstractAutowireCapableBeanFactory#createBeandoCreateBean、populateBean、initializeBean
源码简化流程:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
// 1. 实例化 Bean
Object beanInstance = instantiateBean(beanName, mbd, args);
// 2. 属性填充(依赖注入)
populateBean(beanName, mbd, instanceWrapper);
// 3. 初始化 Bean
bean = initializeBean(beanName, bean, mbd);
return bean;
}
3. Bean 生命周期管理
Spring 会在 Bean 实例化后,执行各种生命周期回调,比如:
BeanPostProcessor(前后置处理)InitializingBean、DisposableBean@PostConstruct、@PreDestroy
源码片段:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1. 执行 BeanPostProcessor.beforeInitialization
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 2. 执行初始化方法(如 InitializingBean、@PostConstruct)
invokeInitMethods(beanName, wrappedBean, mbd);
// 3. 执行 BeanPostProcessor.afterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
4. getBean 的实现
当我们调用 getBean("beanName") 时,Spring 会:
- 检查是否已经创建(单例缓存)
- 如果没有,则走完整的创建流程(如上)
- 返回最终的 Bean 实例
源码简化:
public Object getBean(String name) throws BeansException {
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
return getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// ... 如果没有,则创建
Object bean = doCreateBean(beanName, mbd, args);
return getObjectForBeanInstance(bean, name, beanName, mbd);
}
5. 简单模拟依赖注入(构造器注入)
下面我们扩展前面的 SimpleIOC,实现构造器参数注入:
class SimpleIOC {
private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
private Map<String, Object> singletonBeans = new HashMap<>();
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanDefinitionMap.put(beanName, beanDefinition);
}
public Object getBean(String beanName) throws Exception {
Object bean = singletonBeans.get(beanName);
if (bean != null) return bean;
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (beanDefinition == null) throw new Exception("No bean named " + beanName);
// 构造器注入
Class<?> clazz = beanDefinition.getBeanClass();
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> ctor : constructors) {
Class<?>[] paramTypes = ctor.getParameterTypes();
if (paramTypes.length == 0) {
bean = ctor.newInstance();
break;
} else {
Object[] params = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
// 假定参数名和 beanName 一致
params[i] = getBean(paramTypes[i].getSimpleName());
}
bean = ctor.newInstance(params);
break;
}
}
singletonBeans.put(beanName, bean);
return bean;
}
}
6. Spring IOC 源码阅读建议
- 从
ApplicationContext入手,跟踪refresh()方法 - 重点关注
DefaultListableBeanFactory、AbstractAutowireCapableBeanFactory - 理解 BeanDefinition、BeanFactory、BeanPostProcessor 的关系
7. 总结
Spring IOC 实现的核心就是:
- Bean 定义的加载和注册
- Bean 的实例化和依赖注入
- Bean 的生命周期管理
- Bean 的获取和缓存

3341

被折叠的 条评论
为什么被折叠?



