星空网 > 软件开发 > Java

Spring Ioc代码阅读

1,理解控制反转  

  以前一直说着这个词,然后把它等于上ioc这个词,再等于上代码里一个bean里依赖了其他bean,不用new,用注解,用     依赖对象的获得被反转
  把一个bean中对其他bean的依赖这个事提取出来,统一由一个容器管理,解耦了bean管理和业务的代码(工厂方法模式不就干这事嘛)
     最后,Spring提供了一个IoC容器来管理对象的生命周期、依赖关系,这也是spring的最核心的基础组件。
     其实控制反转也是一种设计模式,的确,从项目层面抽取了管理bean依赖关系,彻底解耦bean注入和业务代码,也是一种软件开发中的思想。
 
Spring Ioc代码阅读
2,IoC容器
     它要完成什么事?
     通过解析bean依赖关系的描述,容器需要创建出项目中所有需要管理的bean,然后注入。
     那么拆成打的两步:1,把依赖关系描述解析成bean;2,把bean注入
     但是,既然是bean之间有依赖关系,当生产一个bean时,它依赖的bean也需要已经产生,所以在一个软件中,触发开始初始化容器的时候是把项目中用到的bean看成树结构的样子,然后一次递归的生产bean,注入。有点像目录结构遍历。
     比如:A依赖B B依赖C,那么A生产时会触发B生产,然后触发C生产。
     所以,我们阅读IoC源码时也会看到这样的实现。
Spring Ioc代码阅读
 
 
3,IoC容器的实现BeanFactory和ApplicationContext
BeanFactory是容器基础设计,ApplicationContext增加了针对企业软件一些扩展功能,应该说后者是前者的高级形态。
 


public interface BeanFactory {  /**   * 用来获取FactoryBean本身的转义符   */  String FACTORY_BEAN_PREFIX = "&";  /**   * 获取容器维护的bean是用名称来指定的   */  Object getBean(String name) throws BeansException;  <T> T getBean(String name, Class<T> requiredType) throws BeansException;  <T> T getBean(Class<T> requiredType) throws BeansException;  Object getBean(String name, Object... args) throws BeansException;  <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;  /**   * 查看容器中是否包含指定name的bean   */  boolean containsBean(String name);  /**   * 判断指定name的bean是否为单例   */  boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  /**   * 判断指定name的bean是否为多例   */  boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;  boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;  Class<?> getType(String name) throws NoSuchBeanDefinitionException;  /**   * 获得bean的所有别名   */  String[] getAliases(String name);}

BeanFactory设计定义了ioc的规范。

DefaultListableBeanFactory <—  
DefaultListableBeanFactory有容器的完整实现,而
public class extends DefaultListableBeanFactory {  /**   * 换了一个reader   */  private final new this);  public throws BeansException {    this(resource, null);  }  public throws BeansException {    super(parentBeanFactory);    this.reader.loadBeanDefinitions(resource);  }}

Spring Ioc代码阅读

 


FileSystem
public class FileSystemextends Abstractpublic FileSystempublic FileSystemsuper(parent);  }  public FileSystemthrows BeansException {    this(new String[] {configLocation}, true, null);  }  public FileSystemthrows BeansException {    this(configLocations, true, null);  }  public FileSystemthrows BeansException {    this(configLocations, true, parent);  }  public FileSystemboolean refresh) throws BeansException {    this(configLocations, refresh, null);  }  /**   * setConfigLocations 将路径字符串解析到自己存资源配置的configLocations里   * 然后调用refresh(),这也是容器初始化的入口   *   */  public FileSystemboolean refresh, ApplicationContext parent)      throws BeansException {    super(parent);    setConfigLocations(configLocations);    if (refresh) {      refresh();    }  }  /**   * 这是这个FileSystem*/  @Override  protected Resource getResourceByPath(String path) {    if (path != null && path.startsWith("/")) {      path = path.substring(1);    }    return new FileSystemResource(path);  }}

 

调用AbstractApplicationContext的refresh方法:

标准的模版方法,这里注意继承链路,嵌套的模版方法调用下来。

  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.        // 扩展点1        invokeBeanFactoryPostProcessors(beanFactory);        // Register bean processors that intercept bean creation.        // 扩展点2        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) {        // Destroy already created singletons to avoid dangling resources.        destroyBeans();        // Reset 'active' flag.        cancelRefresh(ex);        // Propagate exception to caller.        throw ex;      }    }  }

调用AbstractApplicationContext 的obtainFreshBeanFactory方法:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {  // 这要调用子类的实现=>AbstractRefreshableApplicationContext    refreshBeanFactory();    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    if (logger.isDebugEnabled()) {      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);    }    return beanFactory;  }

AbstractRefreshableApplicationContext的refreshBeanFactory

 

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

Abstract

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {    // Create a new // 指定Reader    new // 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);  }  protected void loadBeanDefinitions(throws BeansException, IOException {    Resource[] configResources = getConfigResources();    if (configResources != null) {      reader.loadBeanDefinitions(configResources);    }    String[] configLocations = getConfigLocations();    if (configLocations != null) {      reader.loadBeanDefinitions(configLocations);    }  }

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(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;  }  /*  *最终调用到的实现,这里需要产生Resource,既然用FileSystem*/  public int loadBeanDefinitions(String location, Set<Resource> 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了        Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);        // 这里是解析Resource的入口        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;    }  }

回到AbstractApplicationContext调用getResources方法,resourcePatternResolver用默认的PathMatchingResourcePatternResolver

public Resource[] getResources(String locationPattern) throws IOException {    return this.resourcePatternResolver.getResources(locationPattern);  }public AbstractApplicationContext() {    this.resourcePatternResolver = getResourcePatternResolver();  }  //默认PathMatchingResourcePatternResolverprotected ResourcePatternResolver getResourcePatternResolver() {    return new PathMatchingResourcePatternResolver(this);  }

PathMatchingResourcePatternResolver的getResources实现

public Resource[] getResources(String locationPattern) throws IOException {    Assert.notNull(locationPattern, "Location pattern must not be null");    // 一种是classpath开头 一种没有    if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {      // a class path resource (multiple resources for same name possible)      if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {        // a class path resource pattern        return findPathMatchingResources(locationPattern);      }      else {        // all class path resources with the given name        return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));      }    }    else {      // Only look for a pattern after a prefix here      // (to not get fooled by a pattern symbol in a strange prefix).      int prefixEnd = locationPattern.indexOf(":") + 1;      if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {        // a file pattern        return findPathMatchingResources(locationPattern);      }      else {        // a single resource with the given name        // 使用ResourceLoader来产生Resource        return new Resource[] {getResourceLoader().getResource(locationPattern)};      }    }  }    // 默认使用DefaultResourceLoader来解析路径  public PathMatchingResourcePatternResolver(ClassLoader classLoader) {    this.resourceLoader = new DefaultResourceLoader(classLoader);  }  public ResourceLoader getResourceLoader() {    return this.resourceLoader;  }

DefaultResourceLoader的getResource,而此时返回的Resource是FileSystemResource类型

public Resource getResource(String location) {  Assert.notNull(location, "Location must not be null");  if (location.startsWith("/")) {   // 最终调用子类的getResourceByPath,而这个方法正是FileSystem   return getResourceByPath(location);  }  else if (location.startsWith(CLASSPATH_URL_PREFIX)) {   return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());  }  else {   try {     // Try to parse the location as a URL...     URL url = new URL(location);     return new UrlResource(url);   }   catch (MalformedURLException ex) {     // No URL -> resolve as resource path.     return getResourceByPath(location);   }  }}

可见FileSystem

Spring Ioc代码阅读

 

Resource相当于定位到资源的抽象,下一步就是不同Resource解析资源。

回到AbstractBeanDefinitionReader的loadBeanDefinitions。定位后下一步就是解析Resource的入口:
int loadCount = loadBeanDefinitions(resource);

子类

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {    Assert.notNull(encodedResource, "EncodedResource must not be null");    if (logger.isInfoEnabled()) {      logger.info("Loading  encodedResource.getResource());    }    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();    if (currentResources == null) {      currentResources = new HashSet<EncodedResource>(4);      this.resourcesCurrentlyBeingLoaded.set(currentResources);    }    if (!currentResources.add(encodedResource)) {      throw new BeanDefinitionStoreException(          "Detected cyclic loading of " + encodedResource + " - check your import definitions!");    }    try {     // 终于到了java读取文件熟悉的InputStream了,Recoure->InputStream      InputStream inputStream = encodedResource.getResource().getInputStream();      try {        InputSource inputSource = new InputSource(inputStream);        if (encodedResource.getEncoding() != null) {          inputSource.setEncoding(encodedResource.getEncoding());        }        // 继续解析:InputStream -> Document        return doLoadBeanDefinitions(inputSource, encodedResource.getResource());      }      finally {        inputStream.close();      }    }    catch (IOException ex) {      throw new BeanDefinitionStoreException(          "IOException parsing  encodedResource.getResource(), ex);    }    finally {      currentResources.remove(encodedResource);      if (currentResources.isEmpty()) {        this.resourcesCurrentlyBeingLoaded.remove();      }    }  }

调用到DefaultDocumentLoader实现解析

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)      throws BeanDefinitionStoreException {    try {     // 继续解析:InputStream -> Document      Document doc = doLoadDocument(inputSource, resource);      // 转化:Document->BeanDefinition      // 显然,从一个Document变成一个个bean的描述(BeanDefinition),就涉及到我们在使用spring时经常用到的bean定义时的各种配置规则,如果查看源码,也许会更好的理解。      return registerBeanDefinitions(doc, resource);    }    catch (BeanDefinitionStoreException ex) {      throw ex;    }    catch (SAXParseException ex) {      throw new "Line " + ex.getLineNumber() + " in , ex);    }    catch (SAXException ex) {      throw new ", ex);    }    catch (ParserConfigurationException ex) {      throw new BeanDefinitionStoreException(resource.getDescription(),          "Parser configuration exception parsing  resource, ex);    }    catch (IOException ex) {      throw new BeanDefinitionStoreException(resource.getDescription(),          "IOException parsing  resource, ex);    }    catch (Throwable ex) {      throw new BeanDefinitionStoreException(resource.getDescription(),          "Unexpected exception parsing  resource, ex);    }  }  // 具体documentLoader来实现,DefaultDocumentLoader实现解析  protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {    return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,        getValidationModeForResource(resource), isNamespaceAware());  }

DefaultDocumentLoader使用JAXP方式解析:

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,      ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {    DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);    if (logger.isDebugEnabled()) {      logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");    }    DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);    return builder.parse(inputSource);  }  protected DocumentBuilder createDocumentBuilder(      DocumentBuilderFactory factory, EntityResolver entityResolver, ErrorHandler errorHandler)      throws ParserConfigurationException {    DocumentBuilder docBuilder = factory.newDocumentBuilder();    if (entityResolver != null) {      docBuilder.setEntityResolver(entityResolver);    }    if (errorHandler != null) {      docBuilder.setErrorHandler(errorHandler);    }    return docBuilder;  }

registerBeanDefinitions方法:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();    int countBefore = getRegistry().getBeanDefinitionCount();    //BeanDefinitionDocumentReader具体实现    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));    return getRegistry().getBeanDefinitionCount() - countBefore;  }

BeanDefinitionDocumentReader具体实现:

public void registerBeanDefinitions(Document doc, this.readerContext = readerContext;    logger.debug("Loading bean definitions");    Element root = doc.getDocumentElement();    doRegisterBeanDefinitions(root);  }    protected void doRegisterBeanDefinitions(Element root) {    // Any nested <beans> elements will cause recursion in this method. In    // order to propagate and preserve <beans> 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;    // 指定好BeanDefinitionParserDelegate    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;        }      }    }  //可扩展入口    preProcessthis.delegate);    postProcessthis.delegate = parent;  }    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);    }  }  //标签解析  private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {     //import      importBeanDefinitionResource(ele);    }    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {     //alias      processAliasRegistration(ele);    }    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {     //bean      processBeanDefinition(ele, delegate);    }    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {      // beans recurse      doRegisterBeanDefinitions(ele);    }  }

如果是beans的标签则进行了递归,查看解析bean标签的代码:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {  // 终于是解析入口了,Element->BeanDefinitionHolder    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));    }  }  public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {    return parseBeanDefinitionElement(ele, null);  }

这里的BeanDefinitionHolder包装了BeanDefinition以及bean和alias:

private final BeanDefinition beanDefinition;  private final String beanName;  private final String[] aliases;

BeanDefinitionReaderUtils.registerBeanDefinition:

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { // bean id    String id = ele.getAttribute(ID_ATTRIBUTE);    // bean name    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);    List<String> aliases = new ArrayList<String>();    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 );      }    }    if (containingBean == null) {      checkNameUniqueness(beanName, aliases, ele);    }// beanDefinition产生 此时已经解析了bean中的其他字段    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 );          }        }        catch (Exception ex) {          error(ex.getMessage(), ele);          return null;        }      }      String[] aliasesArray = StringUtils.toStringArray(aliases);      return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);    }    return null;  }

拿到holder后进行注册:

  public static void registerBeanDefinition(      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)      throws BeanDefinitionStoreException {    // Register bean definition under primary name.    String beanName = definitionHolder.getBeanName();    // 把解析出来到BeanDefinition进行注册    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中的代码:

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 (!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<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);          updatedDefinitions.addAll(this.beanDefinitionNames);          updatedDefinitions.add(beanName);          this.beanDefinitionNames = updatedDefinitions;          if (this.manualSingletonNames.contains(beanName)) {            Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);            updatedSingletons.remove(beanName);            this.manualSingletonNames = updatedSingletons;          }        }      }      else {        // Still in startup registration phase        this.beanDefinitionMap.put(beanName, beanDefinition);        this.beanDefinitionNames.add(beanName);        this.manualSingletonNames.remove(beanName);      }      this.frozenBeanDefinitionNames = null;    }    if (oldBeanDefinition != null || containsSingleton(beanName)) {      resetBeanDefinition(beanName);    }  }

 


到这里,组装出了一个beanName:beanDefinition的ConcurrentHashMap,后续就是在这个map作为资源的基础上进行依赖注入的。


 
 
 
Spring Ioc代码阅读

Spring Ioc代码阅读




原标题:Spring Ioc代码阅读

关键词:Spring

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

9月起运费全面开涨!物流巨头更新政策,接棒涨价!大卖却称:毫无压力!已有应对办法?:https://www.ikjzd.com/articles/1562259676685254657
黄峥出海前传,拼多多兄弟公司往事:https://www.ikjzd.com/articles/1562268317031186434
出口退税函调要求企业准备的材料有哪些内容?:https://www.ikjzd.com/articles/1562275956410662914
访问量逆势增长!亚洲跨境平台Allegro大举杀入波兰:https://www.ikjzd.com/articles/1562280430255955969
独立站Shopify推出新产品Shopify Collabs,引领网红带货新潮流:https://www.ikjzd.com/articles/1562280447805812737
给国外客户寄样品,到底要不要收费?:https://www.ikjzd.com/articles/1562281498428424194
秦皇岛到丹东旅游景点大全 秦皇岛到丹东开车多长时间:https://www.vstour.cn/a/408253.html
求推荐适合情侣玩的地方,三天时间,谢谢:https://www.vstour.cn/a/408254.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流