欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > Spring IoC容器源码深度解析

Spring IoC容器源码深度解析

2024/10/25 14:23:39 来源:https://blog.csdn.net/boydoy1987/article/details/141223100  浏览:    关键词:Spring IoC容器源码深度解析

Spring框架的核心是其控制反转(IoC)容器。本文将深入探讨Spring IoC容器的源码实现,包括基本概念、关键接口、bean的生命周期,以及如何解决循环依赖等高级特性,帮助您更好地理解其工作原理。

1. IoC容器概述

IoC(Inversion of Control)是Spring框架的基础,它负责管理对象的创建、配置和生命周期。Spring的IoC容器主要由BeanFactoryApplicationContext接口定义。

2. 核心接口和实现

2.1 BeanFactory接口

BeanFactory是Spring IoC容器的根接口,定义了最基本的IoC功能:

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

DefaultListableBeanFactoryBeanFactory接口的一个重要实现。它负责bean的注册和管理:

public class DefaultListableBeanFactory implements BeanFactory, BeanDefinitionRegistry {private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {this.beanDefinitionMap.put(beanName, beanDefinition);}@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}// 其他方法实现...
}

3. Bean的生命周期

Bean的生命周期是Spring IoC容器的核心功能之一。以下是简化的bean创建流程:

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) {// 1. 解析bean classClass<?> resolvedClass = resolveBeanClass(mbd, beanName);// 2. 准备方法覆盖mbd.prepareMethodOverrides();// 3. 实例化前的处理Object bean = resolveBeforeInstantiation(beanName, mbd);if (bean != null) {return bean;}// 4. 创建beanObject beanInstance = doCreateBean(beanName, mbd, args);return beanInstance;
}

Bean的生命周期主要包括以下阶段:

  1. 实例化
  2. 属性赋值
  3. 初始化
  4. 销毁

Spring提供了多个扩展点来干预Bean的生命周期:

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通过反射机制实现属性注入:

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完成的:

public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {@Overridepublic 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:

  1. singletonObjects:一级缓存,存放完全初始化好的bean
  2. earlySingletonObjects:二级缓存,存放原始的bean对象(尚未填充属性)
  3. singletonFactories:三级缓存,存放bean工厂对象
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 循环依赖的解决过程

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来解决这个问题:

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。不同作用域的实现方式如下:

public class DefaultListableBeanFactory extends ... {@Overridepublic 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通过巧妙的缓存机制和生命周期管理,解决了诸如循环依赖等复杂问题,同时提供了足够的扩展性来满足各种定制需求。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com