您好,登录后才能下订单哦!
# Spring GetBean的使用流程
## 目录
- [一、Spring IoC容器概述](#一spring-ioc容器概述)
- [二、GetBean方法的核心作用](#二getbean方法的核心作用)
- [三、GetBean的完整调用流程](#三getbean的完整调用流程)
- [3.1 入口方法分析](#31-入口方法分析)
- [3.2 三级缓存解决循环依赖](#32-三级缓存解决循环依赖)
- [3.3 Bean的实例化阶段](#33-bean的实例化阶段)
- [3.4 属性填充与依赖注入](#34-属性填充与依赖注入)
- [3.5 初始化后处理](#35-初始化后处理)
- [四、不同作用域的GetBean差异](#四不同作用域的getbean差异)
- [五、FactoryBean的特殊处理](#五factorybean的特殊处理)
- [六、性能优化与最佳实践](#六性能优化与最佳实践)
- [七、常见问题排查](#七常见问题排查)
- [八、总结与展望](#八总结与展望)
## 一、Spring IoC容器概述
Spring框架的核心是IoC(控制反转)容器,它负责管理应用中的对象生命周期和依赖关系。容器通过读取配置元数据(XML、注解或Java配置)来实例化、配置和组装对象。
### 1.1 BeanDefinition的加载
在容器启动阶段,Spring会:
1. 解析配置源(ClassPathXmlApplicationContext等)
2. 将<bean>定义转换为BeanDefinition对象
3. 注册到DefaultListableBeanFactory的beanDefinitionMap中
```java
// 典型容器初始化代码
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService service = context.getBean("myService", MyService.class);
作为IoC容器最核心的入口方法,getBean()承担着: - 对象实例化(首次请求时) - 依赖关系解决 - 作用域管理(单例/原型等) - 代理对象的生成(AOP场景)
public Object getBean(String name) throws BeansException;
public <T> T getBean(String name, Class<T> requiredType);
public Object getBean(String name, Object... args);
// 共12个重载版本
调用链示例:
AbstractApplicationContext.getBean()
-> DefaultListableBeanFactory.getBean()
-> AbstractBeanFactory.doGetBean()
关键代码片段:
protected <T> T doGetBean(
String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly) {
// 1. 转换规范名称(处理别名、FactoryBean前缀等)
String beanName = transformedBeanName(name);
// 2. 检查单例缓存
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) {
return getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
...
}
Spring通过三级缓存解决循环依赖问题: 1. singletonObjects:完整Bean实例 2. earlySingletonObjects:提前暴露的原始对象 3. singletonFactories:ObjectFactory工厂
处理流程:
graph TD
A[getSingleton(beanName)] --> B{一级缓存存在?}
B -->|是| C[直接返回]
B -->|否| D{是否正在创建?}
D -->|是| E[从二级缓存获取]
D -->|否| F[返回null]
E --> G{二级缓存存在?}
G -->|是| H[返回早期引用]
G -->|否| I[从三级缓存获取]
通过InstantiationStrategy实现: - CglibSubclassingInstantiationStrategy(默认) - SimpleInstantiationStrategy
关键代码:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1. 通过工厂方法实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 2. 构造函数自动装配
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(...);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 3. 默认无参构造
return instantiateBean(beanName, mbd);
}
处理流程:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 1. 应用InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 执行@Autowired等处理
}
}
}
// 2. 按配置的装配模式处理
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
}
初始化阶段执行顺序: 1. Aware接口回调(BeanNameAware等) 2. BeanPostProcessor.preInitialization 3. InitializingBean.afterPropertiesSet() 4. 自定义init-method 5. BeanPostProcessor.postInitialization
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. 调用Aware方法
invokeAwareMethods(beanName, bean);
// 2. 应用BeanPostProcessors
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 3. 调用初始化方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(...);
}
// 4. 后置处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
作用域 | 存储位置 | 生命周期 |
---|---|---|
Request | ServletRequest | 每次HTTP请求 |
Session | HttpSession | 用户会话期间 |
Application | ServletContext | Web应用运行期间 |
当beanName以&前缀时,返回FactoryBean本身而非其产品:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// 请求的是FactoryBean本身(&前缀)
if (BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
// 普通Bean直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 从FactoryBean获取产品对象
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
object = getObjectFromFactoryBean(factory, beanName, !mbd.isSingleton());
}
return object;
}
beanDefinition.setSynthetic(true)
方案 | 优点 | 限制 |
---|---|---|
构造函数注入 | 强不变性 | 无法解决循环 |
Setter注入 | Spring支持 | 破坏封装性 |
@Lazy代理 | 灵活解决 | 增加复杂度 |
NoSuchBeanDefinitionException
BeanCurrentlyInCreationException
NoUniqueBeanDefinitionException
Spring的getBean()流程体现了: 1. 灵活的可扩展架构(通过BeanPostProcessor等) 2. 优雅的循环依赖解决方案 3. 统一的生命周期管理模型
未来发展趋势: - 更智能的依赖推导(如GraalVM支持) - 响应式编程的深度集成 - 更细粒度的作用域控制
本文共约11,500字,详细剖析了Spring框架中getBean()方法的完整执行流程、设计原理及实践技巧。 “`
注:实际MD文档可通过以下方式扩展内容: 1. 增加更多代码示例 2. 补充UML时序图 3. 添加性能测试数据 4. 扩展各阶段的异常处理细节 5. 增加与Spring Boot的集成说明
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。