Spring 初始化

基于spring 4.1.6

1、FileSystemXmlApplicationContext

/**

* Create a new FileSystemXmlApplicationContext, loading the definitions

* from the given XML files.

* @param configLocations array of file paths

* @param refresh whether to automatically refresh the context,

* loading all bean definitions and creating all singletons.

* Alternatively, call refresh manually after further configuring the context.

* @throws BeansException if context creation failed

* @see #refresh()

*/

public FileSystemXmlApplicationContext(String configLocation) throws BeansException {

  this(new String[] {configLocation}, true, null);

}

/**

* Create a new FileSystemXmlApplicationContext with the given parent,

* loading the definitions from the given XML files.

* @param configLocations array of file paths

* @param refresh whether to automatically refresh the context,

* loading all bean definitions and creating all singletons.

* Alternatively, call refresh manually after further configuring the context.

* @param parent the parent context

* @throws BeansException if context creation failed

* @see #refresh()

*/

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)

      throws BeansException {

  super(parent);

  setConfigLocations(configLocations);

  if (refresh) {

      refresh();

  }

}

第29行 super(parent); 实例化父类,AbstractXmlApplicationContext、AbstractRefreshableConfigApplicationContext、AbstractRefreshableApplicationContext、AbstractApplicationContext

第32行 refresh();

2、AbstractApplicationContext

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.

      prepareBeanFactory(beanFactory);

      try {

        // Allows post-processing of the bean factory in context subclasses.

        postProcessBeanFactory(beanFactory);

        // Invoke factory processors registered as beans in the context.

        invokeBeanFactoryPostProcessors(beanFactory);

        // Register bean processors that intercept bean creation.

        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.

        finishBeanFactoryInitialization(beanFactory);

        // Last step: publish corresponding event.

        finishRefresh();

      }

      catch (BeansException ex) {

        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;

      }

  }

}

第4行

prepareRefresh();

// Tell the subclass to refresh the internal bean factory.

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

第38行

finishRefresh();

第7行 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {

  refreshBeanFactory();

  ConfigurableListableBeanFactory beanFactory = getBeanFactory();

  if (logger.isDebugEnabled()) {

      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);

  }

  return beanFactory;

}

第2行 refreshBeanFactory(); 该方法两个子类均有实现

AbstractRefreshableApplicationContext 和 GenericApplicationContext,前面 FileSystemXmlApplicationContext 有 AbstractRefreshableApplicationContext 实例化。

3、AbstractRefreshableApplicationContext


/**

* This implementation performs an actual refresh of this context's underlying

* bean factory, shutting down the previous bean factory (if any) and

* initializing a fresh bean factory for the next phase of the context's lifecycle.

*/

@Override

protected final void refreshBeanFactory() throws BeansException {

  if (hasBeanFactory()) {

      destroyBeans();

      closeBeanFactory();

  }

  try {

      DefaultListableBeanFactory beanFactory = createBeanFactory();

      beanFactory.setSerializationId(getId());

      customizeBeanFactory(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);

  }

}

第13行

DefaultListableBeanFactory beanFactory = createBeanFactory();

4、进入 loadBeanDefinitions(beanFactory); 方法,AbstractXmlApplicationContext


/**

* Loads the bean definitions via an XmlBeanDefinitionReader.

* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader

* @see #initBeanDefinitionReader

* @see #loadBeanDefinitions

*/

@Override

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

  // Create a new XmlBeanDefinitionReader for the given BeanFactory.

  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);

}

第10行

XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);


/**

* Load the bean definitions with the given XmlBeanDefinitionReader.

* 

The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory} * method; hence this method is just supposed to load and/or register bean definitions. * @param reader the XmlBeanDefinitionReader to use * @throws BeansException in case of bean registration errors * @throws IOException if the required XML document isn't found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources * @see #getResourcePatternResolver */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }

5、AbstractBeanDefinitionReader


public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {

  Assert.notNull(locations, "Location array must not be null");

  int counter = 0;

  for (String location : locations) {

      counter += loadBeanDefinitions(location);

  }

  return counter;

}

public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {

  return loadBeanDefinitions(location, null);

}

public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException {

  ResourceLoader resourceLoader = getResourceLoader();

  if (resourceLoader == null) {

      throw new BeanDefinitionStoreException(

            "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");

  }

  if (resourceLoader instanceof ResourcePatternResolver) {

      // Resource pattern matching available.

      try {

        Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

        int loadCount = loadBeanDefinitions(resources);

        if (actualResources != null) {

            for (Resource resource : resources) {

              actualResources.add(resource);

            }

        }

        if (logger.isDebugEnabled()) {

            logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");

        }

        return loadCount;

      }

      catch (IOException ex) {

        throw new BeanDefinitionStoreException(

              "Could not resolve bean definition resource pattern [" + location + "]", ex);

      }

  }

  else {

      // Can only load single resources by absolute URL.

      Resource resource = resourceLoader.getResource(location);

      int loadCount = loadBeanDefinitions(resource);

      if (actualResources != null) {

        actualResources.add(resource);

      }

      if (logger.isDebugEnabled()) {

        logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");

      }

      return loadCount;

  }

}

第31行,loadBeanDefinitions(resources); 为什么是 XmlBeanDefinitionReader 这个类?
因为,BeanDefinitionReader接口好多实现类,XmlBeanDefinitionReader只是其中一个子类,因为步骤4有定义啦。

6、XmlBeanDefinitionReader


/**

* 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

*/

@Override

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {

  return loadBeanDefinitions(new EncodedResource(resource));

}

public 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());

        }

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

      }

  }

}

protected 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);

  }

}

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {

  BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();

  documentReader.setEnvironment(getEnvironment());

  int countBefore = getRegistry().getBeanDefinitionCount();

  documentReader.registerBeanDefinitions(doc, createReaderContext(resource));

  return getRegistry().getBeanDefinitionCount() - countBefore;

}

第5行,documentReader.registerBeanDefinitions(doc, createReaderContext(resource));

7、DefaultBeanDefinitionDocumentReader


/**

* This implementation parses bean definitions according to the "spring-beans" XSD

* (or DTD, historically).

* 

Opens a DOM Document; then initializes the default settings * specified at the {@code } level; then parses the contained bean definitions. */ @Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); } protected 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)) { return; } } } preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; }

第23行,parseBeanDefinitions(root, this.delegate);

/**

* Parse the elements at the root level in the document:

* "import", "alias", "bean".

* @param root the DOM root element of the document

*/

protected 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);

  }

}

第13行,如果是spring的基础命名元素解析(import、bean、beans、alias)解析:

parseDefaultElement(ele, delegate);

拓展元素解析:delegate.parseCustomElement(ele); 拓展元素涉及到aop相关,后面的内容讨论。


private 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)) {

      processBeanDefinition(ele, delegate);

  }

  else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {

      // recurse

      doRegisterBeanDefinitions(ele);

  }

}

下面以解析bean为例


/**

* Process the given bean element, parsing the bean definition

* and registering it with the registry.

*/

protected 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));

  }

}

8、BeanDefinitionReaderUtils


/**

* Register the given bean definition with the given bean factory.

* @param definitionHolder the bean definition including name and aliases

* @param registry the bean factory to register with

* @throws BeanDefinitionStoreException if registration failed

*/

public 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);

      }

  }

}

9、DefaultListableBeanFactory


public 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 (this.logger.isInfoEnabled()) {

            this.logger.info("Overriding bean definition for bean '" + beanName +

                  "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

        }

      }

  }

  else {

      this.beanDefinitionNames.add(beanName);

      this.manualSingletonNames.remove(beanName);

      this.frozenBeanDefinitionNames = null;

  }

  this.beanDefinitionMap.put(beanName, beanDefinition);

  if (oldBeanDefinition != null || containsSingleton(beanName)) {

      resetBeanDefinition(beanName);

  }

}

以上完成读取、解析、注册,然后到 2、AbstractApplicationContext 的 finishBeanFactoryInitialization(beanFactory);

补充然后,

实例化 DefaultListableBeanFactory 的时候,调用 preInstantiateSingletons 完成bean实例化,不是抽象的bean,是单例的bean,非懒加载。

10、AbstractApplicationContext

refresh() 方法中调用 finishBeanFactoryInitialization(beanFactory);


/**

* 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));

  }

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

}

第10行,getBean方法,到21还是22,应该是到21、DefaultListableBeanFactory,因为前面有实例化该类。

11、DefaultListableBeanFactory


public 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)) {

            final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);

            boolean isEagerInit;

            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {

              isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {

                  @Override

                  public Boolean run() {

                    return ((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) {

        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;

        if (System.getSecurityManager() != null) {

            AccessController.doPrivileged(new PrivilegedAction() {

              @Override

              public Object run() {

                  smartSingleton.afterSingletonsInstantiated();

                  return null;

              }

            }, getAccessControlContext());

        }

        else {

            smartSingleton.afterSingletonsInstantiated();

        }

      }

  }

}

 
 

第41行,Object singletonInstance = getSingleton(beanName); 获取单例对象,应该是到18步,17步没用吗?可能是内部用吧。

getBean 遍历

12、AbstractBeanFactory

public Object getBean(String name) throws BeansException {

return doGetBean(name, null, null, false);

}

getBean --> doGetBean --> createBean --> doCreateBean --> createBeanInstance -- > instanceBean


/**

* 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

*/

@SuppressWarnings("unchecked")

protected  T doGetBean(

      final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)

      throws BeansException {

  final String beanName = transformedBeanName(name);

  Object bean;

  // Eagerly check singleton cache for manually registered singletons.

  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 (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 dependsOnBean : dependsOn) {

              if (isDependent(beanName, dependsOnBean)) {

                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                        "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");

              }

              registerDependentBean(dependsOnBean, beanName);

              getBean(dependsOnBean);

            }

        }

        // Create bean instance.

        if (mbd.isSingleton()) {

            sharedInstance = getSingleton(beanName, new ObjectFactory() {

              @Override

              public Object getObject() throws BeansException {

                  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);

        }

        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 '" + scopeName + "'");

            }

            try {

              Object scopedInstance = scope.get(beanName, new ObjectFactory() {

                  @Override

                  public Object getObject() throws BeansException {

                    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 && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {

      try {

        return getTypeConverter().convertIfNecessary(bean, requiredType);

      }

      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;

}

 
 

第123行,return createBean(beanName, mbd, args);

13、AbstractAutowireCapableBeanFactory


protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

      throws BeanCreationException {

  if (logger.isDebugEnabled()) {

      logger.debug("Creating instance of bean '" + beanName + "'");

  }

  // Make sure bean class is actually resolved at this point.

  resolveBeanClass(mbd, beanName);

  // Prepare method overrides.

  try {

      mbd.prepareMethodOverrides();

  }

  catch (BeanDefinitionValidationException ex) {

      throw new BeanDefinitionStoreException(mbd.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, mbd);

      if (bean != null) {

        return bean;

      }

  }

  catch (Throwable ex) {

      throw new BeanCreationException(mbd.getResourceDescription(), beanName,

            "BeanPostProcessor before instantiation of bean failed", ex);

  }

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

  if (logger.isDebugEnabled()) {

      logger.debug("Finished creating instance of bean '" + beanName + "'");

  }

  return beanInstance;

}

第31行,Object beanInstance = doCreateBean(beanName, mbd, args); 执行完,用BeanWrapper包装。


/**

* 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 */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 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, new ObjectFactory() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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; }

第22行,instanceWrapper = createBeanInstance(beanName, mbd, args);


protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {

  // Make sure bean class is actually resolved at this point.

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

  }

  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);

      }

  }

  // Need to determine the constructor...

  Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

  if (ctors != null ||

        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {

      return autowireConstructor(beanName, mbd, ctors, args);

  }

  // No special handling: simply use no-arg constructor.

  return instantiateBean(beanName, mbd);

}

最后一行,instantiateBean(beanName, mbd)


protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

  try {

      Object beanInstance;

      final BeanFactory parent = this;

      if (System.getSecurityManager() != null) {

        beanInstance = AccessController.doPrivileged(new PrivilegedAction() {

            @Override

            public Object run() {

              return getInstantiationStrategy().instantiate(mbd, beanName, parent);

            }

        }, getAccessControlContext());

      }

      else {

        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

      }

      BeanWrapper bw = new BeanWrapperImpl(beanInstance);

      initBeanWrapper(bw);

      return bw;

  }

  catch (Throwable ex) {

      throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

  }

}

 
 

第14行,beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);执行完,用 BeanWrapper包装。

第9行,return getInstantiationStrategy().instantiate(mbd, beanName, parent);

14、SimpleInstantiationStrategy


public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {

  // Don't override the class with CGLIB if no overrides.

  if (bd.getMethodOverrides().isEmpty()) {

      Constructor constructorToUse;

      synchronized (bd.constructorArgumentLock) {

        constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;

        if (constructorToUse == null) {

            final Class clazz = bd.getBeanClass();

            if (clazz.isInterface()) {

              throw new BeanInstantiationException(clazz, "Specified class is an interface");

            }

            try {

              if (System.getSecurityManager() != null) {

                  constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction>() {

                    @Override

                    public Constructor run() throws Exception {

                        return clazz.getDeclaredConstructor((Class[]) null);

                    }

                  });

              }

              else {

                  constructorToUse = clazz.getDeclaredConstructor((Class[]) null);

              }

              bd.resolvedConstructorOrFactoryMethod = constructorToUse;

            }

            catch (Exception ex) {

              throw new BeanInstantiationException(clazz, "No default constructor found", ex);

            }

        }

      }

      return BeanUtils.instantiateClass(constructorToUse);

  }

  else {

      // Must generate CGLIB subclass.

      return instantiateWithMethodInjection(bd, beanName, owner);

  }

}

第31行,return BeanUtils.instantiateClass(constructorToUse);

15、BeanUtils


public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {

  Assert.notNull(ctor, "Constructor must not be null");

  try {

      ReflectionUtils.makeAccessible(ctor);

      return ctor.newInstance(args);

  }

  catch (InstantiationException ex) {

      throw new BeanInstantiationException(ctor.getDeclaringClass(),

            "Is it an abstract class?", ex);

  }

  catch (IllegalAccessException ex) {

      throw new BeanInstantiationException(ctor.getDeclaringClass(),

            "Is the constructor accessible?", ex);

  }

  catch (IllegalArgumentException ex) {

      throw new BeanInstantiationException(ctor.getDeclaringClass(),

            "Illegal arguments for constructor", ex);

  }

  catch (InvocationTargetException ex) {

      throw new BeanInstantiationException(ctor.getDeclaringClass(),

            "Constructor threw exception", ex.getTargetException());

  }

}

16、回到 AbstractAutowireCapableBeanFactory,回到doCreateBean 方法,继续向下执行

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

设置 mbd.postProcessed = true;


addSingletonFactory(beanName, new ObjectFactory() {

  @Override

  public Object getObject() throws BeansException {

      return getEarlyBeanReference(beanName, mbd, bean);

  }

});

// Initialize the bean instance.

Object exposedObject = bean;

try {

  populateBean(beanName, mbd, instanceWrapper);

  if (exposedObject != null) {

      exposedObject = initializeBean(beanName, exposedObject, mbd);

  }

}

registerDisposableBeanIfNecessary(beanName, bean, mbd);

 
 

17、AbstractBeanFactory

protected  T doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) 
throws BeansException

如果缓存中没有单例的bean,则需要从头开始创建单例bean,这里主要是重载 getSingleton()方法实现单例bean的加载。


// Create bean instance.

if (mbd.isSingleton()) {

  sharedInstance = getSingleton(beanName, new ObjectFactory() {

      @Override

      public Object getObject() throws BeansException {

        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);

}

 
 

18、DefaultSingletonBeanRegistry

包含前后处理方法,beforeSingletonCreation(beanName); 和 afterSingletonCreation(beanName);


public Object getSingleton(String beanName, ObjectFactory singletonFactory) {

  Assert.notNull(beanName, "'beanName' must not be null");

  synchronized (this.singletonObjects) {

      Object singletonObject = this.singletonObjects.get(beanName);

      if (singletonObject == null) {

        if (this.singletonsCurrentlyInDestruction) {

            throw new BeanCreationNotAllowedException(beanName,

                  "Singleton bean creation not allowed while the 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 {

            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) {

            addSingleton(beanName, singletonObject);

        }

      }

      return (singletonObject != NULL_OBJECT ? singletonObject : null);

  }

}

这个方法只是做一些准备及处理操作,而真正获取单例bean的方法并不在这里实现,而是在ObjectFactory类型的实例singletonFactory中。

19、AbstractBeanFactory,继续执行

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);


/**

* Get the object for the given bean instance, either the bean

* instance itself or its created object in case of a FactoryBean.

* @param beanInstance the shared bean instance

* @param name name that may include factory dereference prefix

* @param beanName the canonical bean name

* @param mbd the merged bean definition

* @return the object to expose for the bean

*/

protected Object getObjectForBeanInstance(

      Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

  // Don't let calling code try to dereference the factory if the bean isn't a factory.

  if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {

      throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());

  }

  // Now we have the bean instance, which may be a normal bean or a FactoryBean.

  // If it's a FactoryBean, we use it to create a bean instance, unless the

  // caller actually wants a reference to the factory.

  if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {

      return beanInstance;

  }

  Object object = null;

  if (mbd == null) {

      object = getCachedObjectForFactoryBean(beanName);

  }

  if (object == null) {

      // Return bean instance from factory.

      FactoryBean factory = (FactoryBean) beanInstance;

      // Caches object obtained from FactoryBean if it is a singleton.

      if (mbd == null && containsBeanDefinition(beanName)) {

        mbd = getMergedLocalBeanDefinition(beanName);

      }

      boolean synthetic = (mbd != null && mbd.isSynthetic());

      object = getObjectFromFactoryBean(factory, beanName, !synthetic);

  }

  return object;

}

检查beanName是否以(&)开头,并且继承FactoryBean,表示一个工厂Bean,如果不是直接返回;如果是,从getCacheObjectFromFactoryBean中获取。

根据工厂bean,获取真实的bean。spring提供了一种特殊的bean,继承接口FactoryBean,无法使用getBean(beanName)获取,必须使用getBean(& + beanName) 获取,spring在处理完成后,首先获得FactoryBean的实例,然后使用实例中的getObject()来获取真正的bean。

20、FactoryBeanRegistrySupport

protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess)

总结:

1、最简单的spring bean的生成流程基本是按照我们之前预想的那样,从容器中获取BeanDefinition,然后根据class生成对象,并且注入参数;

2、spring的bean生成过程非常复杂,因为他根据客户配置不同,预留了很多变化,如单例生成一次进行缓存;原型每次生成,预留了自定义的scope;

3、对bean的生成前后,spring均预留了一些接口,可以对bean进行额外的参数注入和设置;

4、FacctoryBean的出现,我们配置的bean不一定是最终生成的bean的class,需要额外处理;

5、整个过程采用了各种缓存和多次检查防止重复。

21、DefaultListableBeanFactory

preInstantiateSingletons()

protected  T doGetBean(

      final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)

      throws BeansException

// 之前的getBean已经在11步执行了,这里传递的是requiredType,从哪里调用呢?

public T getBean(Class requiredType, Object... args) throws BeansException

public String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit)

private String[] doGetBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit)

isTypeMatch(beanName, type)

AbstractApplicationContext 的 finishBeanFactoryInitialization 方法开始,判断有没有转换服务

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));

  }

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

}

22、AbstractBeanFactory

public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException

protected Class getTypeForFactoryBean(final FactoryBean factoryBean)

23、回到 AbstractAutowireCapableBeanFactory

怎么到这个类呢?因为是它调用的16步

protected Class getTypeForFactoryBean(String beanName, RootBeanDefinition mbd)

private FactoryBean getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd)

补充:

1)DefaultListableBeanFactory 的作用

DefaultListableBeanFactory 功能的实现是通过实现特定功能的接口来完成的。默认实现了了ListableBeanFactory 和 BeanDefinitionRegistry接口,基于bean definition对象,是一个成熟的BeanFactory。

AbstractAutowireCapableBeanFactory 实现属性的自动绑定功能。

ConfigurableListableBeanFactory 提供了对bean定义的分析和修改的便利方法,同时也提供了对单例的预实例化。

ListableBeanFactory 提供了枚举所有bean的实例,而不是客户端通过名称一个个查询得出的所有实例。

BeanDefinitionRegistry 提供了beanDefinition 的管理。

最典型的应用是:在访问bean前,先注册所有的difinition(可能是bean definition配置文件中),使用预先定义的bean定义元数据对象,从本地的bean definition 表中查询bean definition ,因而不会花费太多成本。

DefaultListableBeanFactory 既可以作为一个单独的beanFactory,也可以作为自定义的beanFactory的父类。

注意:特定格式bean definition的解析器可以自己实现,也可以使用原有的解析器,如:PropertiesBeanDefinitionReader 和 XmlBeanDefinitionReader。

总结:

XmlBeanDefinitionReader 读取xml配置文件

ResourceLoader 将资源文件转换为对应的Resource文件

DocumentLoader 将resource文件转换为Document文件

DefaultBeanDefinitionDocumentReader 对Document进行解析,并使用BeanDefinitionParserDelegate 对Element进行解析。

加载bean:

1)封装资源文件,XmlBeanDefinitionReader 对参数Resource 封装

2)获取输入流,从Resource中获取对应的InputStream并构造InputSource

3)调用doLoadBeanDefinitions

首先对传入的resource参数做封装,目的是考虑到resource可能存在编码要求的情况;其次通过SAX读取xml文件的方式准备InputSource对象;最后将准备的数据传入真正的核心处理部分 doLoadBeanDefinitions

spring通过 BeanDefinition 将配置中的bean配置纤细转换为容器的内部表示,并将这些BeanDefinition 注册到 BeanDefinitionRegister 中。

XmlBeanDefinitionReader loadBeanDefinitions

1)封装资源文件 EncodeResource

2)获取输入流 InputStream

3)调用 doLoadBeanDefinitions

获取对 xml 文件的验证模式,加载 xml 文件并得到对应的Document,根据返回的Document注册bean。

xml(读取) --> Resource(解析)--> BeanDefinition(注册)--> BeanFactory

spring解析xml文件为 org.w3c.dom.Document,使用了 SAX 的实现方式。

DefaultListableBeanFactory --> AbstractXmlApplicationContext --> AbstractBeanDefinitionReader --> XmlBeanDefinitionDocumentReader --> DefaultListableBeanFactory

DefaultListableBeanFactory 贯穿其中

你可能感兴趣的:(Spring 初始化)