spring_ioc
ioc容器
spring bean的容器
控制反转ioc(Inversion of Control)指的是将我们手动创建bean的操作交给ioc容器,让ioc容器去负责管理bean的生命周期
BeanFactory
The root interface for accessing a Spring bean container
负责生产和管理 bean 实例的工厂,但是此接口只提供了对单个 bean 的操作接口,功能有限,所以才有了结构图中如此之多的接口用来扩展功能
1 | public interface BeanFactory { |
1)ListableBeanFactory
Listable 的意思就是,通过这个接口,我们可以获取多个 Bean,提供了获取多个bean的许多方法
2)HierarchicalBeanFactory
Hierarchical 分层的意思,指可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系,例如spring mvc
3)AutowireCapableBeanFactory
Autowire 自动装配的意思,提供自动依赖注入的能力
ApplicationContext
Central interface to provide configuration for an application.
为应用提供配置的核心接口,在运行期是只读的,只提供重载功能
ApplicationContext 的具体实现,都是通过父类组合的 DefaultListableBeanFactory 属性来提供容器功能的,而 DefaultListableBeanFactory 则间接的继承了 ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory,提供了最完整的 BeanFactory 功能
1 | public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { |
1)ClassPathXmlApplicationContext
classpath路径下xml配置ioc容器
2)AnnotationConfigApplicationContext
java注解方式配置ioc容器
3)FileSystemXmlApplicationContext
文件系统路径下xml配置ioc容器
ioc容器的启动
环境搭建
1 | <dependency> |
1 | //Application.java |
1)refresh方法(主流程)
创建 ioc 容器
1 | //work.icql.test.Application#main |
refresh方法
加载所有的 bean definition 并创建单例bean,ApplicationContext 建立起来以后,可以通过调用 refresh() 这个方法重建
1 |
|
2)prepareRefresh 方法(创建容器准备工作)
1 | //记录容器启动时间、设置启动/关闭标志位(AtomicBoolean) |
3)obtainFreshBeanFactory 方法(创建容器并加载注册bean定义)
初始化 BeanFactory、加载 Bean、注册 Bean 等
1 | //调用 AbstractApplicationContext#obtainFreshBeanFactory |
(1)customizeBeanFactory 方法
1 | //bean定义覆盖问题: |
(2)loadBeanDefinitions 方法
1 | //调用AbstractXmlApplicationContext#loadBeanDefinitions |
4)prepareBeanFactory 方法(准备bean容器)
1 | //调用AbstractApplicationContext#prepareBeanFactory |
5)finishBeanFactoryInitialization 方法(初始化非延迟加载的单例bean)
1 | protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { |
6)finishRefresh 方法(应用启动完成)
1 | protected void finishRefresh() { |
bean的生命周期
bean的生命周期从 getBean 方法开始
调用 AbstractBeanFactory # doGetBean,里面包含了初始化bean的逻辑
1)doGetBean方法(主流程)
1 | protected <T> T doGetBean( |
2)createBean 方法(创建bean实例)
流程较长,只展示重要的逻辑 createBean() -> doCreateBean()
1 | protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) |
(1)createBeanInstance 方法(创建bean实例)
1 | protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args){ |
(2)populateBean 方法(属性装配,依赖注入)
1 | protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw){ |
(3)initializeBean 方法(bean实例化属性装配后的各种回调)
1 | protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd){ |
(4)循环引用问题
spring只能解决属性注入引起的循环依赖,构造方法注入引起的解决不了
基本原理:
bean实例的初始化分为2步:1)半成品bean实例,2)属性值注入
假设 A->B,B->A:
A1完成(放入二级map或三级map)
A2注入属性值B时发现依赖B(一、二、三级map中都找不到)
A2暂停
B1完成
B2注入属性值A时发现依赖A(一找不到,二或三级map可以找到)
B2完成
B完成
A2完成
A完成
1 | //解决循环引用的3个map |
1 | protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
https://segmentfault.com/a/1190000015221968
https://blog.csdn.net/qq_35457078/article/details/112409302
同一个类多个代理类时还是会报循环引用错误,例如同一个类使用了@Transactional、@Async,具体分析
https://blog.csdn.net/luoyang_java/article/details/105835112
3)getObjectForBeanInstance 方法(处理bean实例,FactoryBean)
1 | protected Object getObjectForBeanInstance( |
4)bean生命周期图

赞赏是不耍流氓的鼓励