# 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。