Spring启动流程(二)——获取BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

该方法对BeanFactory进行刷新。如果刷新前已经存在一个BeanFactory则需要先进行关闭操作,而后初始化一个新BeanFactory。

protected final void refreshBeanFactory() throws BeansException {
    // 判断是否已经存在一个BeanFactory 
    if (hasBeanFactory()) {
        // 销毁已经存在BeanFactory中的所有Bean
        destroyBeans();
        // 关闭BeanFactory
        closeBeanFactory();
    }
    try {
        // 创建新的BeanFactory对象(DefaultListableBeanFactory)
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        // 给BeanFactory设置Id
        beanFactory.setSerializationId(getId());
        // 该方法主要对2个标志进行设置:allowBeanDefinitionOverriding和allowCircularReferences
        // allowBeanDefinitionOverriding:是否允许使用相同名称重新注册不同的bean(Spring默认true,SpringBoot默认false)
        // allowCircularReferences:是否允许循环依赖
        customizeBeanFactory(beanFactory);
        // 加载配置文件
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            // 新创建的BeanFactory赋给成员变量beanFactory
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

DefaultSingletonBeanRegistry

/ 当前这个单例是否正在被销毁
// true:表示单例已经执行了destroy方法,或者出现异常时执行了destroySingleton方法
private boolean singletonsCurrentlyInDestruction = false;

// 缓存两个Bean之间的包含关系。如:一个Bean中包含了一个内部Bean。
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

// 缓存Bean与其他依赖Bean的关系
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

// 缓存被依赖Bean与其他依赖Bean的关系
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

// 销毁所有的Bean实例
public void destroySingletons() {
    if (logger.isDebugEnabled()) {
        logger.debug("Destroying singletons in " + this);
    }
    synchronized (this.singletonObjects) {
        // 设置销毁标志
        this.singletonsCurrentlyInDestruction = true;
    }

    // 销毁disposableBeans缓存中所有单例bean
    String[] disposableBeanNames;
    synchronized (this.disposableBeans) {
        disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
    }
    for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
        destroySingleton(disposableBeanNames[i]);
    }

    // 清空包含关系
    this.containedBeanMap.clear();
    // 清空依赖和被依赖关系
    this.dependentBeanMap.clear();
    this.dependenciesForBeanMap.clear();

    // 清空缓存
    clearSingletonCache();
}

加载配置

在这里插入图片描述
AbstractXmlApplicationContext

protected 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

@Override
// 通过String数组参数locations加载Bean,并返回加载Bean的数量
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int counter = 0;
    for (String location : locations) {
        // 加载BeanDefinintion
        counter += loadBeanDefinitions(location);
    }
    // 返回加载Bean的数量
    return counter;
}

@Override
// 通过Resource数组参数locations加载Bean,并返回加载Bean的数量
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int counter = 0;
    for (Resource resource : resources) {
        // 加载BeanDefinintion
        counter += loadBeanDefinitions(resource);
    }
    // 返回加载Bean的数量
    return counter;
}

XmlBeanDefinitionReader

在这里插入代码片// 从配置文件中加载Bean
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);
    }

    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 {
        // 将Resource资源转化为输入流InputStream
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }
            // 执行加载Bean的过程
            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();
        }
    }
}

// 加载Bean的函数
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    throws BeanDefinitionStoreException {
    try {
        // 加载XML文件,构造XML Document对象
        Document doc = doLoadDocument(inputSource, resource);
        // 注册Bean
        return registerBeanDefinitions(doc, resource);
    }
    // 抛出各种异常
    ......
}

Bean的解析与注册

在这里插入图片描述
DefaultBeanDefinitionDocumentReader

// XML配置文件中beans元素
public static final String NESTED_BEANS_ELEMENT = "beans";
// XML配置文件中alias别名元素
public static final String ALIAS_ELEMENT = "alias";
// XML配置文件中name属性
public static final String NAME_ATTRIBUTE = "name";
// XML配置文件中alias属性
public static final String ALIAS_ATTRIBUTE = "alias";
// XML配置文件中import元素
public static final String IMPORT_ELEMENT = "import";
// XML配置文件中resource属性
public static final String RESOURCE_ATTRIBUTE = "resource";
// XML配置文件中profile属性
public static final String PROFILE_ATTRIBUTE = "profile";

protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
    // 创建Bean解析代理工具类
    this.delegate = createDelegate(getReaderContext(), root, parent);

    if (this.delegate.isDefaultNamespace(root)) {
        // 解析profile属性
        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);
    // 解析XML并执行Bean注册
    parseBeanDefinitions(root, this.delegate);
    postProcessXml(root);

    this.delegate = parent;
}

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // root根节点是默认标签
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        // 遍历XML Document的每个节点
        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);
                }
            }
        }
    }
    // root根节点是自定义标签
    else {
        delegate.parseCustomElement(root);
    }
}

// 解析XML配置文件的节点元素
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    // 如果是Import元素
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // 如果是Alias别名元素
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    // 如果是Bean元素
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
    // 如果是嵌套Bean元素(Beans)
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}

Import解析

虽然每个单独的XML配置文件都代表体系结构中的逻辑层或模块,但我们可以从多个XML片段中加载Bean定义。如项目中有多个Resource位置,可以使用一个或多个从另外的XML文件中加载Bean定义。
标签用法示例:

<import resource="applicationDao.xml" />
<import resource="applicationService.xml" />

解析标签的源码:
DefaultBeanDefinitionDocumentReader

protected void importBeanDefinitionResource(Element ele) {
    String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
    if (!StringUtils.hasText(location)) {
        getReaderContext().error("Resource location must not be empty", ele);
        return;
    }

    // 解析路径和占位符
    location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location);

    // 解析好的资源要放到Set里面
    Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

    // 解析location是相对路径还是绝对路径
    boolean absoluteLocation = false;
    try {
        absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
    }
    catch (URISyntaxException ex) {
        // cannot convert to an URI, considering the location relative
        // unless it is the well-known Spring prefix "classpath*:"
    }

    // 如果是绝对路径
    if (absoluteLocation) {
        try {
            // 直接根据路径加载相应的配置文件
            int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
            }
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error(
                "Failed to import bean definitions from URL location [" + location + "]", ele, ex);
        }
    }
    else {
        try {
            int importCount;
            // 如果是相对路径,则先根据路径得到Resource
            Resource relativeResource = getReaderContext().getResource().createRelative(location);
            // 如果Resource存在
            if (relativeResource.exists()) {
                importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                actualResources.add(relativeResource);
            }
            else {
                // Resource类解析不成功,在classpath路径中去加载。如果没有则抛出异常
                String baseLocation = getReaderContext().getResource().getURL().toString();
                importCount = getReaderContext().getReader().loadBeanDefinitions(
                    StringUtils.applyRelativePath(baseLocation, location), actualResources);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
            }
        }
        catch (IOException ex) {
            getReaderContext().error("Failed to resolve current resource location", ele, ex);
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
                                     ele, ex);
        }
    }
    Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
    getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
}

Alias别名注册

每个bean具有一个或多个标识符。这些标识符在承载Bean的容器内必须是唯一的。 Bean通常只有一个标识符,但是如果需要多个标识符,则多余的标识符可以被视为别名。
标签用法示例:

<alias name="dataSource" alias="systemA-dataSource"/>
<alias name="dataSource" alias="systemB-dataSource"/>

在Bean定义中,可以通过使用id属性最多指定的一个名称,同时可以通过name属性中定义任意数量的其他名称来为Bean提供多个名称。但在定义Bean的地方指定所有别名可能并不能满足需求,有时需要在其他地方为Bean定义别名。
解析标签的源码:
SimpleAliasRegistry

// 存放别名的缓存
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>

// 根据Bean的别名进行注册
public void registerAlias(String name, String alias) {
    Assert.hasText(name, "'name' must not be empty");
    Assert.hasText(alias, "'alias' must not be empty");
    synchronized (this.aliasMap) {
        // 如果别名和名字相同
        if (alias.equals(name)) {
            this.aliasMap.remove(alias);
        }
        else {
            // 如果别名和名字不相同,根据别名获取Bean名称
            String registeredName = this.aliasMap.get(alias);
            if (registeredName != null) {
                // 如果缓存中已经存在该别名,不需要注册到缓存
                if (registeredName.equals(name)) {
                    // An existing alias - no need to re-register
                    return;
                }
                // 如果不允许相同的Bean使用不同的名称则抛出异常
                if (!allowAliasOverriding()) {
                    throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" +
                                                    name + "': It is already registered for name '" + registeredName + "'.");
                }
            }
            // 对别名进行循环检查
            checkForAliasCircle(name, alias);
            // 把别名放入别名缓存
            this.aliasMap.put(alias, name);
        }
    }
}

// 别名循环检查
public boolean hasAlias(String name, String alias) {
    for (Map.Entry<String, String> entry : this.aliasMap.entrySet()) {
        // 获取Bean注册名
        String registeredName = entry.getValue();
        // 判断name参数和Bean注册名是否相同
        if (registeredName.equals(name)) {
            // 获取别名
            String registeredAlias = entry.getKey();
            // 判断别名是否相同
            // 递归调用hasAlias
            if (registeredAlias.equals(alias) || hasAlias(registeredAlias, alias)) {
                return true;
            }
        }
    }
    return false;
}

别名循环检查:A为名称,B为A的别名,需要注册别名<B, A>

  1. 检查B是否有别名,如果没有则返回false
  2. 如果B有别名C,检查C是否与A相同。如果相同返回true,说明有别名循环。如果不相同递归hasAlias(C, B)方法
  3. 如果C无别名,返回false;如果C有别名D且等于A,返回true。如果不相同继续递归hasAlias(D, B)

Bean注册

在这里插入图片描述
Spring会自动检测构造型类,并向容器注册相应的BeanDefinition。
DefaultBeanDefinitionDocumentReader

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 解析XML中的BeanDefinition元素
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 注册BeanDefinition
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        // 发送注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

BeanDefinitionParserDelegate
基于单一职责的缘故,BeanDefinitionParserDelegate专门负责解析XML元素的工作,而DefaultBeanDefinitionDocumentReader则主要负责读取XML配置文件的职责。

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    // 获取id属性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    // 获取name属性
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    // 定义别名list
    List<String> aliases = new ArrayList<String>();
    if (StringUtils.hasLength(nameAttr)) {
        // 因为可以多个别名用,所以解析成别名数组
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }

    // beanName默认为id
    String beanName = id;
    // 如果没有beanName,那么取出别名数组中的第一个作为beanName
    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) {
                    // 生成Bean名
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                        beanDefinition, this.readerContext.getRegistry(), true);
                }
                else {
                    // 生成Bean名
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    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;
}

// 解析Bean定义不考虑名称或别名。如果在Bean解析过程中产生异常,则返回null
public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, BeanDefinition containingBean) {

    this.parseState.push(new BeanEntry(beanName));

    String className = null;
    // 解析Bean的class属性
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }

    try {
        String parent = null;
        // 解析parent属性
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }
        // 为指定的类名和Parent名称创建一个BeanDefinition
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);

        // 解析Bean元素的属性并应用于Bean
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        // 设置Bean的描述信息
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

        // 解析Bean定义的元数据信息(meta以键值对形式存在)
        parseMetaElements(ele, bd);
        // 解析lookup-method元素
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        // 解析replaced-method元素
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

        // 解析构造函数参数
        parseConstructorArgElements(ele, bd);
        // 解析property元素
        parsePropertyElements(ele, bd);
        // 解析qualifier元素
        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
该类的主要职责用于生产新的BeanDefiniti实例,给Bean生成一个名称及调用BeanDefinitionRegistry进行Bean的注册。

public static String generateBeanName(
    BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
    throws BeanDefinitionStoreException {

    String generatedBeanName = definition.getBeanClassName();
    if (generatedBeanName == null) {
        // 如果有父类,名称为:definition.getParentName() + “$child”
        if (definition.getParentName() != null) {
            generatedBeanName = definition.getParentName() + "$child";
        }
        // 如果有指定的工厂类,名称为:definition.getFactoryBeanName() + “$created”
        else if (definition.getFactoryBeanName() != null) {
            generatedBeanName = definition.getFactoryBeanName() + "$created";
        }
    }
    if (!StringUtils.hasText(generatedBeanName)) {
        throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
                                               "'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
    }

    String id = generatedBeanName;
    if (isInnerBean) {
        // 如果是innerBean,名称为
        id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
    }
    else {
        // 如果不是InnerBean则为顶层Bean,使用简单的类名。计数器加1
        int counter = -1;
        while (counter == -1 || registry.containsBeanDefinition(id)) {
            counter++;
            id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter;
        }
    }
    return id;
}
  • parent
    Bean定义可以包含许多配置信息,包括容器相关的信息(比如初始化方法,静态工厂方法等等)以及构造函数参数和属性的值。子Bean可以定义从父Bean定义中继承配置数据,而后它可以根据需要覆盖某些值,或添加其他值。使用父子Bean可以节省很多输入工作。
  • lookup-method
    lookup-method注入是容器重写Bean上的方法的一种能力,它可以在容器中根据一个Bean的名字返回查找结果。lookup-method通常涉及Prototype Bean。Spring框架通过使用CGLIB来覆盖该方法的子类以实现lookup-method的注入。该功能可用于在一些可插拔的功能上解除依赖。
  • replace-method
    用于在运行时调用使用新的方法替换原有的方法,还能动态的改变原有方法的逻辑。

DefaultListableBeanFactory

// 手动注册的单例名称列表
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);

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属性中的methodOverrides校验
            // 校验methodOverrides是否与工厂方法并存或者methodOverrides对应的方法根本不存在
            ((AbstractBeanDefinition) beanDefinition).validate();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Validation of bean definition failed", ex);
        }
    }

    // 从缓存中根据beanName获取BeanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
        // 如果BeanDefinition存在并且不允许同名覆盖,则抛出异常
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                                                   "': There is already [" + existingDefinition + "] bound.");
        }
        // Bean的角色检查
        else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isWarnEnabled()) {
                logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
            }
        }
        // 如果名字相同,但是BeanDefinition不同打印覆盖日志
        else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isInfoEnabled()) {
                logger.info("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
            }
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                             "' with an equivalent definition: replacing [" + existingDefinition +
                             "] with [" + beanDefinition + "]");
            }
        }
        // 在缓存中注册Bean
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
        // 检查工厂的Bean创建阶段是否已经开始
        if (hasBeanCreationStarted()) {
            // 进入创建阶段,此时无法再修改启动时集合元素(为了稳定迭代)
            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;
                // beanName在manualSingletonNames中,说明是手动注册
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        }
        else {
            // 工厂还未到创建阶段,仍然在注册阶段
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    // 待注册的Bean的已经在beanDefinitionMap缓存中存在,或者已经存在于单例Bean缓存中
    if (existingDefinition != null || containsSingleton(beanName)) {
        // 重置给定Bean的所有BeanDefinition缓存,包括从其派生的Bean的缓存
        resetBeanDefinition(beanName);
    }
}

AbstractBeanFactory

// 保存在至少被创建过一次的beanName
// 如果这个集合中存在beanName,那么说明已经进入了Bean创建阶段
private final Set<String> alreadyCreated =
			Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(256))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值