博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring IOC源码解析
阅读量:6259 次
发布时间:2019-06-22

本文共 50632 字,大约阅读时间需要 168 分钟。

hot3.png

Spring的核心是IoC容器和AOP,它们是Spring架构体系中的核心基础。平常使用通过简单配置即可,没有深究其底层实现,因而常常不知所以然,殊不知Spring已经帮助我们完成了太多事情。因此有必要对其实现进行学习,加深对其的理解和应用。

IoC(Inverse of Control):控制反转,将对象的创建权利交由Spring来管理。

继承体系

IoC容器的实现又依赖于BeanFactory和ApplicationContext,ApplicationContext继承BeanFactory并添加了一系列高级功能。先来看看主要的接口继承结构: IoC容器主要接口继承结构

ApplicationContext的继承体系: ApplicationContext继承体系

IoC容器的初始化过程

容器创建和Bean加载解析及注册

下面以最常用的 ClassPathXmlApplicationContext 为例来分析初始化过程,首先由构造方法启动初始化过程。

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {   @Nullable   private Resource[] configResources;   /**    * Create a new ClassPathXmlApplicationContext for bean-style configuration.    * @see #setConfigLocation    * @see #setConfigLocations    * @see #afterPropertiesSet()    */   public ClassPathXmlApplicationContext() {   }   public ClassPathXmlApplicationContext(ApplicationContext parent) {      super(parent);   }   //该构造方法允许指定BeanDefinition所在文件路径   public ClassPathXmlApplicationContext(String configLocation) throws BeansException {      this(new String[] {configLocation}, true, null);   }   public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {      this(configLocations, true, null);   }   //该构造方法允许指定多个BeanDefinition的文件路径,并允许指定父IoC容器   public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)         throws BeansException {      this(configLocations, true, parent);   }   public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {      this(configLocations, refresh, null);   }   //在对象初始化过程中,调用refresh方法载入BeanDefinition,refresh是IoC容器初始化的核心方法,由此启动了初始化过程   public ClassPathXmlApplicationContext(         String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)         throws BeansException {      super(parent);      setConfigLocations(configLocations);      if (refresh) {         refresh();      }   }}

分析启动初始化过程的refresh方法

// AbstractApplicationContext 516@Overridepublic void refresh() throws BeansException, IllegalStateException {   synchronized (this.startupShutdownMonitor) {      //准备刷新 包含设置启动时间、设置状态...      prepareRefresh();      //实现刷新BeanFactory,将配置文件解析为BeanDefinition并注册到BeanFactory,此时Bean还未被初始化      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();      // Prepare the bean factory for use in this context.      prepareBeanFactory(beanFactory);      try {         //设置BeanFactory的后置处理         postProcessBeanFactory(beanFactory);         //调用BeanFactory的后置处理器,后置处理器在Bean定义中向容器注册         invokeBeanFactoryPostProcessors(beanFactory);         //注册Bean的后置处理器,在Bean创建过程中调用         registerBeanPostProcessors(beanFactory);         //初始化上下文的消息源         initMessageSource();         //初始化上下文的事件机制         initApplicationEventMulticaster();         //初始化其它的特定的bean         onRefresh();         //检查Bean监听器并向容器注册         registerListeners();	//实例化所有单例bean(排除lazy-init)          finishBeanFactoryInitialization(beanFactory);         //发布完成事件,结束初始化过程         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();      }   }}
// AbstractApplicationContext 620protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {   refreshBeanFactory();   ConfigurableListableBeanFactory beanFactory = getBeanFactory();   if (logger.isDebugEnabled()) {      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);   }   return beanFactory;}

BeanDefinition载入交互过程 BeanDefinition载入交互过程

// AbstractRefreshableApplicationContext 131@Overrideprotected final void refreshBeanFactory() throws BeansException {   /**    * 判断应用上下文是否存在BeanFactory 有则销毁所有bean 关闭BeanFactory    */   if (hasBeanFactory()) {      destroyBeans();      closeBeanFactory();   }   try {      // 初始化一个新的DefaultListableBeanFactory      DefaultListableBeanFactory beanFactory = createBeanFactory();      beanFactory.setSerializationId(getId());      // 设置BeanFactory的两个属性 是否允许Bean覆盖、循环引用      customizeBeanFactory(beanFactory);      // 加载BeanDefinitions至BeanFactory      loadBeanDefinitions(beanFactory);      synchronized (this.beanFactoryMonitor) {         this.beanFactory = beanFactory;      }   } catch (IOException ex) {      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);   }}
/** * 使用 XmlBeanDefinitionReader 加载 BeanDefinitions */// AbstractXmlApplicationContext 84@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {   //给当前 BeanFactory 初始化一个 XmlBeanDefinitionReader   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);   // Configure the bean definition reader with this context's   // resource loading environment.   beanDefinitionReader.setEnvironment(this.getEnvironment());   beanDefinitionReader.setResourceLoader(this);   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));   // Allow a subclass to provide custom initialization of the reader,   // then proceed with actually loading the bean definitions.   initBeanDefinitionReader(beanDefinitionReader);   loadBeanDefinitions(beanDefinitionReader);}
// AbstractXmlApplicationContext 127protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {   //以Resource方式获取配置文件的资源位置   Resource[] configResources = getConfigResources();   if (configResources != null) {      reader.loadBeanDefinitions(configResources);   }   //以String形式获取配置文件的位置    String[] configLocations = getConfigLocations();   if (configLocations != null) {      reader.loadBeanDefinitions(configLocations);   }}
// AbstractBeanDefinitionReader 183@Overridepublic int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {   Assert.notNull(resources, "Resource array must not be null");   int counter = 0;   for (Resource resource : resources) {      counter += loadBeanDefinitions(resource);   }   return counter;}
/** * Load bean definitions from the specified XML file. * @param resource the resource descriptor for the XML file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */// XmlBeanDefinitionReader 302@Overridepublic int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {   return loadBeanDefinitions(new EncodedResource(resource));}/** * Load bean definitions from the specified XML file. * @param encodedResource the resource descriptor for the XML file, * allowing to specify an encoding to use for parsing the file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors */// XmlBeanDefinitionReader 313public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {   Assert.notNull(encodedResource, "EncodedResource must not be null");   if (logger.isInfoEnabled()) {      logger.info("Loading XML bean definitions from " + encodedResource.getResource());   }   Set
currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //执行加载BeanDefinitions核心方法 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } }}/** * Actually load bean definitions from the specified XML file. * @param inputSource the SAX InputSource to read from * @param resource the resource descriptor for the XML file * @return the number of bean definitions found * @throws BeanDefinitionStoreException in case of loading or parsing errors * @see #doLoadDocument * @see #registerBeanDefinitions */// XmlBeanDefinitionReader 388protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { Document doc = doLoadDocument(inputSource, resource); return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); }}// XmlBeanDefinitionReader 505public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { //使用BeanDefinitionDocumentReader解析XML的BeanDefinition BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore;}
// DefaultBeanDefinitionDocumentReader 94@Overridepublic void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {   this.readerContext = readerContext;   logger.debug("Loading bean definitions");   Element root = doc.getDocumentElement();   doRegisterBeanDefinitions(root);}/** * Register each bean definition within the given root {@code 
} element. */// DefaultBeanDefinitionDocumentReader 122protected void doRegisterBeanDefinitions(Element root) { // Any nested
elements will cause recursion in this method. In // order to propagate and preserve
default-* attributes correctly, // keep track of the current (parent) delegate, which may be null. Create // the new (child) delegate with a reference to the parent for fallback purposes, // then ultimately reset this.delegate back to its original (parent) reference. // this behavior emulates a stack of delegates without actually necessitating one. BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent;}/** * Parse the elements at the root level in the document: * "import", "alias", "bean". * @param root the DOM root element of the document */// DefaultBeanDefinitionDocumentReader 167protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); }}// DefaultBeanDefinitionDocumentReader 188private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { //处理Bean标签定义 processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse 递归调用 doRegisterBeanDefinitions(ele); }}/** * Process the given bean element, parsing the bean definition * and registering it with the registry. */// DefaultBeanDefinitionDocumentReader 305protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // Register the final decorated instance. BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); }}
// BeanDefinitionParserDelegate  404@Nullablepublic BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {   return parseBeanDefinitionElement(ele, null);}// BeanDefinitionParserDelegate 414@Nullablepublic BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {   String id = ele.getAttribute(ID_ATTRIBUTE);   String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);   List
aliases = new ArrayList<>(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isDebugEnabled()) { logger.debug("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null;}// BeanDefinitionParserDelegate 500@Nullablepublic AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, @Nullable BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } try { AbstractBeanDefinition bd = createBeanDefinition(className, parent); parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //解析Bean标签的子元素 parseMetaElements(ele, bd); parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); parseConstructorArgElements(ele, bd); parsePropertyElements(ele, bd); parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null;}
// BeanDefinitionReaderUtils 144public static void registerBeanDefinition(      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)      throws BeanDefinitionStoreException {   // Register bean definition under primary name.   String beanName = definitionHolder.getBeanName();   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());   // Register aliases for bean name, if any.   String[] aliases = definitionHolder.getAliases();   if (aliases != null) {      for (String alias : aliases) {         registry.registerAlias(beanName, alias);      }   }}
// DefaultListableBeanFactory 789@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)      throws BeanDefinitionStoreException {   Assert.hasText(beanName, "Bean name must not be empty");   Assert.notNull(beanDefinition, "BeanDefinition must not be null");   if (beanDefinition instanceof AbstractBeanDefinition) {      try {         ((AbstractBeanDefinition) beanDefinition).validate();      }      catch (BeanDefinitionValidationException ex) {         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,               "Validation of bean definition failed", ex);      }   }   BeanDefinition oldBeanDefinition;   oldBeanDefinition = this.beanDefinitionMap.get(beanName);   if (oldBeanDefinition != null) {      if (!isAllowBeanDefinitionOverriding()) {         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,               "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +               "': There is already [" + oldBeanDefinition + "] bound.");      }      else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE         if (this.logger.isWarnEnabled()) {            this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +                  "' with a framework-generated bean definition: replacing [" +                  oldBeanDefinition + "] with [" + beanDefinition + "]");         }      }      else if (!beanDefinition.equals(oldBeanDefinition)) {         if (this.logger.isInfoEnabled()) {            this.logger.info("Overriding bean definition for bean '" + beanName +                  "' with a different definition: replacing [" + oldBeanDefinition +                  "] with [" + beanDefinition + "]");         }      }      else {         if (this.logger.isDebugEnabled()) {            this.logger.debug("Overriding bean definition for bean '" + beanName +                  "' with an equivalent definition: replacing [" + oldBeanDefinition +                  "] with [" + beanDefinition + "]");         }      }      this.beanDefinitionMap.put(beanName, beanDefinition);   }   else {      if (hasBeanCreationStarted()) {         // Cannot modify startup-time collection elements anymore (for stable iteration)         synchronized (this.beanDefinitionMap) {            this.beanDefinitionMap.put(beanName, beanDefinition);            List
updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set
updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { //将BeanDefinition添加到BeanDefinitionMap中 this.beanDefinitionMap.put(beanName, beanDefinition); //将bean名称添加到list中 this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); }}

容器配置处理

主要包括下面操作:

  • 准备BeanFactory
  • BeanFactory后置处理的设置、调用和注册
  • 初始化上下文消息源
  • 初始化上下文事件机制
  • 检查Bean监听器并向容器注册
// AbstractApplicationContext 516@Overridepublic void refresh() throws BeansException, IllegalStateException {   synchronized (this.startupShutdownMonitor) {      //准备刷新 包含设置启动时间、设置状态...      prepareRefresh();      //实现刷新BeanFactory,将配置文件解析为BeanDefinition并注册到BeanFactory,此时Bean还未被初始化      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();      // Prepare the bean factory for use in this context.      prepareBeanFactory(beanFactory);      try {         //设置BeanFactory的后置处理         postProcessBeanFactory(beanFactory);         //调用BeanFactory的后置处理器,后置处理器在Bean定义中向容器注册         invokeBeanFactoryPostProcessors(beanFactory);         //注册Bean的后置处理器,在Bean创建过程中调用         registerBeanPostProcessors(beanFactory);         //初始化上下文的消息源         initMessageSource();         //初始化上下文的事件机制         initApplicationEventMulticaster();         //初始化其它的特定的bean         onRefresh();         //检查Bean监听器并向容器注册         registerListeners();	//实例化所有单例bean(排除lazy-init)          finishBeanFactoryInitialization(beanFactory);         //发布完成事件,结束初始化过程         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();      }   }}

初始化单例Bean

非延迟初始化Bean实例创建过程

非延迟初始化Bean实例创建过程

/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */// AbstractApplicationContext 841protected 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 bean post-processor   // (such as a PropertyPlaceholderConfigurer 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.   beanFactory.preInstantiateSingletons();}
// DefaultListableBeanFactory 727@Overridepublic void preInstantiateSingletons() throws BeansException {   if (this.logger.isDebugEnabled()) {      this.logger.debug("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.   List
beanNames = new ArrayList<>(this.beanDefinitionNames); // 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)) { //处理FactoryBean 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
) ((SmartFactoryBean
) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean
) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { //处理普通Bean,直接调用getBean(beanName)方法进行初始化 getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } }}
// AbstractBeanFactory 198@Overridepublic Object getBean(String name) throws BeansException {   return doGetBean(name, null, null, false);}/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */// AbstractBeanFactory 239@SuppressWarnings("unchecked")protected 
T doGetBean(final String name, @Nullable final Class
requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; //从缓存获取Bean,处理已经被创建过的单例Bean,无需重复创建 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = 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 { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current 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); } } } //创建单例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; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //创建多例Bean 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); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //其它类型 else { String scopeName = mbd.getScope(); final 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); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean;}
// AbstractAutowireCapableBeanFactory 464@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   if (logger.isDebugEnabled()) {      logger.debug("Creating instance of bean '" + beanName + "'");   }   RootBeanDefinition mbdToUse = mbd;   // Make sure bean class is actually resolved at this point, and   // clone the bean definition in case of a dynamically resolved Class   // which cannot be stored in the shared merged bean definition.   Class
resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); }}/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. *

Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */// AbstractAutowireCapableBeanFactory 534protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //由createBeanInstance方法创建Bean if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class

beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set
actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;}

主要包含下下面三个主要方法:

  • createBeanInstance
  • populateBean
  • initializeBean

createBeanInstance方法用于创建Bean实例

/** * Create a new instance for the specified bean, using an appropriate instantiation strategy: * factory method, constructor autowiring, or simple instantiation. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a BeanWrapper for the new instance * @see #obtainFromSupplier * @see #instantiateUsingFactoryMethod * @see #autowireConstructor * @see #instantiateBean */// AbstractAutowireCapableBeanFactory 1090protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {   //确认需要创建Bean的类可以实例化   Class
beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier
instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //使用工厂方法对Bean进行实例化 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } //使用构造方法进行实例化 Constructor
[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //使用默认无参构造方法对Bean进行实例化 return instantiateBean(beanName, mbd);}

populateBean方法主要给Bean进行属性注入

/** * Populate the bean instance in the given BeanWrapper with the property values * from the bean definition. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param bw BeanWrapper with bean instance */// AbstractAutowireCapableBeanFactory 1287protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {   if (bw == null) {      if (mbd.hasPropertyValues()) {         throw new BeanCreationException(               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");      }      else {         // Skip property population phase for null instance.         return;      }   }   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the   // state of the bean before properties are set. This can be used, for example,   // to support styles of field injection.   boolean continueWithPropertyPopulation = true;   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {      for (BeanPostProcessor bp : getBeanPostProcessors()) {         if (bp instanceof InstantiationAwareBeanPostProcessor) {            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {               continueWithPropertyPopulation = false;               break;            }         }      }   }   if (!continueWithPropertyPopulation) {      return;   }   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);   //开始进行依赖注入过程,先处理autowired注入   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);            // Add property values based on autowire by name if applicable.      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {         autowireByName(beanName, mbd, bw, newPvs);      }      // Add property values based on autowire by type if applicable.      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {         autowireByType(beanName, mbd, bw, newPvs);      }      pvs = newPvs;   }   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);   if (hasInstAwareBpps || needsDepCheck) {      if (pvs == null) {         pvs = mbd.getPropertyValues();      }      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);      if (hasInstAwareBpps) {         for (BeanPostProcessor bp : getBeanPostProcessors()) {            if (bp instanceof InstantiationAwareBeanPostProcessor) {               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);               if (pvs == null) {                  return;               }            }         }      }      if (needsDepCheck) {         checkDependencies(beanName, mbd, filteredPds, pvs);      }   }   if (pvs != null) {      //对属性进行注入      applyPropertyValues(beanName, mbd, bw, pvs);   }}

initializeBean方法主要处理各种回调

/** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * 

Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */// AbstractAutowireCapableBeanFactory 1688protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean;}

至此,整个IoC容器初始化完成,不容易。

参考资料

Spring技术内幕:深入解析Spring架构与设计原理

深入分析Java Web技术内幕

转载于:https://my.oschina.net/LaravelShao/blog/1827720

你可能感兴趣的文章
Mongodb(2)创建数据库,删除数据库,创建集合,删除集合,显示文档内容
查看>>
Tomcat禁止显示目录和文件列表
查看>>
linux mmap 详解【转】
查看>>
注释中不允许出现字符串 "--"。
查看>>
client 如何找到正确的RegionServer(HBase -ROOT-和.META.表)
查看>>
协议森林16 小美的桌号(DHCP协议)
查看>>
简单的ajax封装
查看>>
PHP初学者必须掌握的10个知识点
查看>>
[Asp.Net]获取客户端ip和mac地址
查看>>
Arcengine设置坐标系(转载)
查看>>
php字符串操作集锦
查看>>
【WPF】C#代码动态改变控件的样式
查看>>
P1115 最大子段和
查看>>
【翻译自mos文章】检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法...
查看>>
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
查看>>
php max_execution_time执行时间问题
查看>>
Hystrix系列-5-Hystrix的资源隔离策略
查看>>
005-ant design -结合echart
查看>>
TCP交互数据流 成块数据流
查看>>
位置+推荐
查看>>