Spring如何解决循环依赖问题

本文详细介绍了Spring在初始化对象时如何处理循环依赖的问题,通过三级缓存机制来确保Bean的正确创建。在创建Bean过程中,当遇到循环依赖时,Spring会将半成品Bean的引用放入二级缓存,并在后续处理中完成代理对象的构建。文章最后探讨了三级缓存的必要性,提出在某些情况下二级缓存可能已足够。
摘要由CSDN通过智能技术生成

首先是ioc的创建流程简图

初始化对象时的循环依赖问题

这个问题出现在上图applicationContext.refresh()方法中,再生成Bean对象时出现的

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      //准备BeanFactory的前置工作
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         //生产BeanFactoryPostProcess对象
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         //执行BeanFactoryPostProcess对象的方法处理BeanDefintion的信息
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         //准备BeanPostProcessor对象
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         //国际化
         initMessageSource();

         // Initialize event multicaster for this context.
         //准备事件监听
         initApplicationEventMulticaster(); 

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         //注册监听器
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //生产Bean
         finishBeanFactoryInitialization(beanFactory);  

         // Last step: publish corresponding event.
         finishRefresh();
      }
      ...
   }
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  ...
   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();
}

然后循环BeanDefintion的信息getBean(创建Bean)

@Override
public void preInstantiateSingletons() throws BeansException {
  ...
   // Trigger initialization of all non-lazy singleton beans...
   for (String beanName : beanNames) {
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         if (isFactoryBean(beanName)) {
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                              ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFact
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值