Administrator
发布于 2022-10-08 / 50 阅读
0
0

Spring源码--IOC

IOC:

 1、IOC是一个容器
 2、容器启动的时候创建所有单实例对象
 3、我们可以直接从容器中获取到这个对象

SpringIOC:

 1)、ioc容器的启动过程?启动期间都做了什么(什么时候创建所有单实例bean)
 2)、ioc是如何创建这些单实例bean,并如何管理的;到底保存在了那里?

思路:从HelloWorld开始,调试每个方法的作用

    public void test() {
        //ioc一创建完成,所有的单实例bean都在里面,step into....
        ApplicationContext ioc = new ClassPathXmlApplicationContext("web.xml");
        context.getBean(Person.class);
    }
//将web.xml整成一个String[]数组
this(new String[] {configLocation}, true, null);

image-1665232274269

ClassPathXmlApplicationContext的构造器有很多个,但最终都会调用下面这个三个参数的构造方法

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(
	String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
	throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
        //refresh一放行,所有的单实例bean都完成了创建
		refresh();
		}
	}

refresh()实现

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
	StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        //Spring解析xml配置文件将要创建的所有bean的配置信息保存起来,可以观看Spring对xml的解析
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

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

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            // 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();
        }

        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        }

        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
            contextRefresh.end();
        }
    }
}

finishBeanFactoryInitialization(beanFactory)实现

finishBeanFactoryInitialization

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
 
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no BeanFactoryPostProcessor
    // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    //初始化所有单实例bean
    beanFactory.preInstantiateSingletons();
}

beanFactory.preInstantiateSingletons()实现

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

  // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  //拿到所有要创建的bean的名字
  List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  // Trigger initialization of all non-lazy singleton beans...
  //按顺序创建bean
  for (String beanName : beanNames) {
  //根据beandid获取到bean的定义信息;
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //判断bean是单实例的,并且不是抽象的,并且不是懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
      //是否是一个实现了FactoryBean接口的bean
          if (isFactoryBean(beanName)) {
              Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
              if (bean instanceof FactoryBean) {
                  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 SmartFactoryBean &&
                              ((SmartFactoryBean<?>) factory).isEagerInit());
                  }
                  if (isEagerInit) {
                      getBean(beanName);
                  }
              }
          }
          else {
              getBean(beanName);
          }
      }
  }

  // Trigger post-initialization callback for all applicable beans...
  for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
          StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
                  .tag("beanName", beanName);
          SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
          if (System.getSecurityManager() != null) {
              AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                  smartSingleton.afterSingletonsInstantiated();
                  return null;
              }, getAccessControlContext());
          }
          else {
              smartSingleton.afterSingletonsInstantiated();
          }
          smartInitialize.end();
      }
  }
}

getBean(beanName);细节

public Object getBean(String name) throws BeansException {
		//所有的getBean掉的是它
		return doGetBean(name, null, null, false);
	}

doGetBean()

protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {

    String beanName = transformedBeanName(name);
    Object beanInstance;

    // Eagerly check singleton cache for manually registered singletons.
     //先从已经注册的所有单实例bean中看有没有个bean。第一次创建bean是没有的;
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                .tag("beanName", name);
        try {
            if (requiredType != null) {
                beanCreation.tag("beanType", requiredType::toString);
            }
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
             //拿到创建当前bean之前需要提前创建的bean。depends-on属性;如果有就循环创建
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            // Create bean instance.创建bean实例
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                }
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new ScopeNotActiveException(beanName, scopeName, ex);
                }
            }
        }
        catch (BeansException ex) {
            beanCreation.tag("exception", ex.getClass().toString());
            beanCreation.tag("message", String.valueOf(ex.getMessage()));
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
        finally {
            beanCreation.end();
        }
    }

    return adaptBeanInstance(name, beanInstance, requiredType);
}

DefaultSingletonBeanRegistry类

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

getSingleton方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "Bean name must not be null");
  synchronized (this.singletonObjects) {
  //singletonObjects就是一个map
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
          if (this.singletonsCurrentlyInDestruction) {
              throw new BeanCreationNotAllowedException(beanName,
                      "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                      "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
          }
          if (logger.isDebugEnabled()) {
              logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
          }
          beforeSingletonCreation(beanName);
          boolean newSingleton = false;
          boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
          if (recordSuppressedExceptions) {
              this.suppressedExceptions = new LinkedHashSet<>();
          }
          try {
          //创建bean
          // return createBean(beanName, mbd, args); lamada表达式创建
              singletonObject = singletonFactory.getObject();
              newSingleton = true;
          }
          catch (IllegalStateException ex) {
              // Has the singleton object implicitly appeared in the meantime ->
              // if yes, proceed with it since the exception indicates that state.
              singletonObject = this.singletonObjects.get(beanName);
              if (singletonObject == null) {
                  throw ex;
              }
          }
          catch (BeanCreationException ex) {
              if (recordSuppressedExceptions) {
                  for (Exception suppressedException : this.suppressedExceptions) {
                      ex.addRelatedCause(suppressedException);
                  }
              }
              throw ex;
          }
          finally {
              if (recordSuppressedExceptions) {
                  this.suppressedExceptions = null;
              }
              afterSingletonCreation(beanName);
          }
          if (newSingleton) {
          //添加创建的bean
              addSingleton(beanName, singletonObject);
          }
      }
      return singletonObject;
  }
}


AbstractAutowireCapableBeanFactory.createBean

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

---
doCreateBean
--
instanceWrapper = createBeanInstance(beanName, mbd, args);

--
createBeanInstance
--
return instantiateBean(beanName, mbd);

--
instantiateBean
--
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

--
getInstantiationStrategy
--
protected InstantiationStrategy getInstantiationStrategy() {
		return this.instantiationStrategy;
	}
--    
instantiationStrategy(instantiate)
--
return BeanUtils.instantiateClass(constructorToUse);

--
BeanUtils
--
//利用反射创建bean
return ctor.newInstance(argsWithDefaultValues);

如果已有bean实例

//最终还是调用doGetBean方法
return doGetBean(name, requiredType, args, false);

--
doGetBean
--
return adaptBeanInstance(name, beanInstance, requiredType);

--
adaptBeanInstance
--
return (T) bean;

总结

创建好的对象最终会保存在一个map中;
ioc容器之一:保存单实例bean的地方;
ioc就是一个容器,单实例bean保存在一个map中;
DefaultSingletonBeanRegistry-singletonObjects
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

BeanFactory和ApplicationContext的区别;

ApplicationContext是BeanFactory的子接口;
BeanFactory:bean工厂接口;负责创建bean实例;容器里面保存的所有单例bean其实是一个map;
          Spring最底层的接口;
ApplicationContext:是容器接口;更多的负责容器功能的实现;
			(可以基于beanFactory创建好的对象之上完成强大的容器)
           容器可以从map获取这个bean,并且aop。di。在ApplicationContext接口的下的这些类里面;

BeanFactory最底层的接口,ApplicationContext留给程序员使用的ioc容器接口;ApplicationContext是
BeanFactory的子接口; ApplicationContext Spring里面最大的模式就是工厂模式;
          <bean class=""></bean>
          BeanFactory:bean工厂;工厂模式;帮用户创建bean

评论