Spring框架的核心是其控制反转(IoC)容器。本文将深入探讨Spring IoC容器的源码实现,包括基本概念、关键接口、bean的生命周期,以及如何解决循环依赖等高级特性,帮助您更好地理解其工作原理。
1. IoC容器概述
IoC(Inversion of Control)是Spring框架的基础,它负责管理对象的创建、配置和生命周期。Spring的IoC容器主要由BeanFactory
和ApplicationContext
接口定义。
2. 核心接口和实现
2.1 BeanFactory接口
BeanFactory
是Spring IoC容器的根接口,定义了最基本的IoC功能:
java
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
// 其他方法...
}
2.2 DefaultListableBeanFactory
DefaultListableBeanFactory
是BeanFactory
接口的一个重要实现。它负责bean的注册和管理:
java
public class DefaultListableBeanFactory implements BeanFactory, BeanDefinitionRegistry {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 其他方法实现...
}
3. Bean的生命周期
Bean的生命周期是Spring IoC容器的核心功能之一。以下是简化的bean创建流程:
java
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 解析bean class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// 2. 准备方法覆盖
mbd.prepareMethodOverrides();
// 3. 实例化前的处理
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
// 4. 创建bean
Object beanInstance = doCreateBean(beanName, mbd, args);
return beanInstance;
}
Bean的生命周期主要包括以下阶段:
- 实例化
- 属性赋值
- 初始化
- 销毁
Spring提供了多个扩展点来干预Bean的生命周期:
java
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
void destroy() throws Exception;
}
4. 依赖注入
依赖注入是IoC的核心特性。Spring通过反射机制实现属性注入:
java
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (pvs != null && !pvs.isEmpty()) {
for (PropertyValue pv : pvs.getPropertyValues()) {
String propertyName = pv.getName();
Object value = pv.getValue();
// 解析引用并注入
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
value = getBean(ref.getBeanName());
}
// 通过反射设置属性
bw.setPropertyValue(propertyName, value);
}
}
}
4.1 @Autowired的工作原理
@Autowired
注解的处理是由AutowiredAnnotationBeanPostProcessor
完成的:
java
public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
// ...
}
5. 循环依赖问题
循环依赖是指两个或多个bean相互依赖的情况。Spring通过三级缓存机制巧妙地解决了这个问题。
5.1 三级缓存
Spring使用三个Map来缓存bean:
singletonObjects
:一级缓存,存放完全初始化好的beanearlySingletonObjects
:二级缓存,存放原始的bean对象(尚未填充属性)singletonFactories
:三级缓存,存放bean工厂对象
java
public class DefaultSingletonBeanRegistry {
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// ...
}
5.2 循环依赖的解决过程
java
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从一级缓存查找
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果一级缓存没有,且当前bean正在创建中,则从二级缓存查找
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 如果二级缓存也没有,且允许提前引用,则从三级缓存查找
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 将bean从三级缓存升级到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
return singletonObject;
}
6. AOP与循环依赖
当涉及到AOP代理和循环依赖时,Spring通过在singletonFactories
中存储一个ObjectFactory
来解决这个问题:
java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
// ...
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ...
}
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
7. Bean的作用域
Spring支持多种bean作用域,最常用的是singleton和prototype。不同作用域的实现方式如下:
java
public class DefaultListableBeanFactory extends ... {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) {
// ...
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// ...
}
}
结论
通过对Spring IoC容器源码的深入分析,我们可以看到其精妙的设计和实现。Spring通过巧妙的缓存机制和生命周期管理,解决了诸如循环依赖等复杂问题,同时提供了足够的扩展性来满足各种定制需求。