Bean在refreshContext过程中创建
Bean加载过程
- SpringApplication.refresh(ApplicationContext applicationContext);
- AbstractApplicationContext.refresh();
- AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory);
- DefaultListableBeanFactory.preInstantiateSingletons();
- 此方法会判断是否为工程Bean,工厂Bean会有特殊处理,然后都会走下一个方法。
- AbstractBeanFactory.getBean(String name),继续进入doGetBean方法;
- DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
- 第一次调此方法(其实并非第一次执行),选去一级缓存Map<String, Object> singletonObjects中拿Bean,为空;
- 再去二级缓存Map<String, Object> earlySingletonObjects中拿Bean,也为空;
- 最后去三级缓存Map<String, ObjectFactory<?>> singletonFactories中拿ObjectFactory,也为空;
- 继续执行,调用DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法
- singletonFactory是一个lambda表达式,会去调AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法;
- 此方法的返回值就是一个初始化完成的对象。
- 进入createBean方法,会调doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)方法
- BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args):反射获取类的构造方法进行实例化,并获得对象的包装类
- final Object bean = instanceWrapper.getWrappedInstance():这里就是构造的Bean示例,是原生的,没有依赖注入
- addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)):这里就是把Bean工厂添加到三级缓存,其中getEarlyBeanReference方法主要是针对AOP进行处理,非代理对象获得的就是对象本身,AOP获得的就是代理对象
- populateBean(beanName, mbd, instanceWrapper):这里完成依赖的注入
- 回到DefaultSingletonBeanRegistry.getSingleton方法,继续执行addSingleton(beanName, singletonObject),把对象放到一级缓存
- 这里已经得到了依赖注入完成的完整对象,就可以把Bean实例加入到一级缓存了。
循环依赖过程
结合Bean加载过程,加入有A和B的循环依赖,那么循环依赖解决过程如下:
- A进行Bean构造,首先把A加入到三级缓存;
- A进行依赖注入,发现依赖B,就去加载B;
- B进行Bean构造,首先把B加入到三级缓存;
- B进行依赖注入,发现依赖A,就去加载A;
- 这时候在三级缓存中找到A,此时就会调用ObjectFactory方法创建A,放入二级缓存,并从三级缓存移除;
- B完成依赖注入,然后移除二级和三级缓存B,加入到一级缓存;
- A获得B的依赖,完成依赖注入,然后移除二级和三级缓存B,加入到一级缓存。