国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

BeanDefinition注冊(cè)-上篇

UCloud / 3204人閱讀

摘要:注冊(cè)上篇前言上文說到已經(jīng)加載完畢,此時(shí)到了注冊(cè)的時(shí)候。創(chuàng)建新的子委托,該委托具有對(duì)父委托的引用,用于備份,然后最終將重置回其原始父引用。這種行為模擬了一堆委托,實(shí)際上并不需要委托。下篇中也會(huì)補(bǔ)充一些此文中關(guān)于注冊(cè)的細(xì)節(jié)內(nèi)容。

BeanDefinition注冊(cè)-上篇 前言
上文說到Document已經(jīng)加載完畢,此時(shí)到了Spring注冊(cè)BeanDefinition的時(shí)候。下面就一起來探究下Spring是怎么把Xml文檔注冊(cè)成BeanDefinition的吧。
XmlBeanDefinitionReader.registerBeanDefinitions
registerBeanDefinitions方法
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    //1. 創(chuàng)建BeanDefinitionDocumentReader
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    //2. 設(shè)置documentReader的環(huán)境
    documentReader.setEnvironment(getEnvironment());
    //3. 查詢之前注冊(cè)的BeanDefinition的個(gè)數(shù)
    int countBefore = getRegistry().getBeanDefinitionCount();
    //4. 開始注冊(cè)BeanDefinition,注意里面創(chuàng)建了一個(gè)Reader上下文
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    //5. 計(jì)算此次注冊(cè)的BeanDefinition的個(gè)數(shù)
    return getRegistry().getBeanDefinitionCount() - countBefore;
}
創(chuàng)建BeanDefinitionDocumentReader
使用BeanUtils創(chuàng)建一個(gè)DefaultBeanDefinitionDocumentReader對(duì)象,用于解析成BeanDefinition對(duì)象
private Class documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
//創(chuàng)建一個(gè)BeanDefinitionDocumentReader,此處使用的是DefaultBeanDefinitionDocumentReader
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
    //利用反射機(jī)制,調(diào)用DefaultBeanDefinitionDocumentReader的構(gòu)造函數(shù),然后創(chuàng)建一個(gè)實(shí)例返回
    return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
}
createReaderContext(resource)
創(chuàng)建一個(gè)XmlReaderContext

設(shè)置了命名空間解析器為DefaultNamespaceHandlerResolver

protected XmlReaderContext createReaderContext(Resource resource) {
    if (this.namespaceHandlerResolver == null) {
        this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
    }
    return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
                                this.sourceExtractor, this, this.namespaceHandlerResolver);
}
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
    return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
}
DefaultNamespaceHandlerResolver
用來處理不同的命名空間的解析器,這些映射規(guī)則是配置在META-INF/spring.handlers文件中(見附圖)

比如對(duì)于xmlns為http://www.springframework.org/schema/c的命名空間的處理器為org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler

public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";

public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
    //設(shè)置類加載器和handlerMapping文件的位置
    this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) {
    Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
    this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
    this.handlerMappingsLocation = handlerMappingsLocation;
}

documentReader.registerBeanDefinitions
注冊(cè)beanDefinition
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    logger.debug("Loading bean definitions");
    //獲取xml的根元素
    Element root = doc.getDocumentElement();
    //注冊(cè)BeanDefinition
    doRegisterBeanDefinitions(root);
}

protected void doRegisterBeanDefinitions(Element root) {
    //獲取 profile 屬性值,我此處并沒有設(shè)置此屬性值,所以使用的是默認(rèn)的
    String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
    //如果有配置profile,則進(jìn)入
    if (StringUtils.hasText(profileSpec)) {
        //將profile放入一個(gè)數(shù)組中
        //profile可以配置多個(gè),中間以MULTI_VALUE_ATTRIBUTE_DELIMITERS(,或;)分隔
        String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
            profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        //判斷環(huán)境是否接受此profile數(shù)組,如果環(huán)境中不允許就直接返回,不再進(jìn)行注冊(cè)
        //這就是為什么pfofile起作用的原因,和環(huán)境中的prfile不一致的配置,不會(huì)被Spring注冊(cè)到容器中
        if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {
            return;
        }
    }

    // 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.
    //任何嵌套的元素都將導(dǎo)致此方法中的遞歸。在為了正確地傳播和保存缺省-*屬性,跟蹤當(dāng)前(父)委托,它可能為空。創(chuàng)建新的(子)委托,該委托具有對(duì)父委托的引用,用于備份,然后最終將this.delegate重置回其原始(父)引用。這種行為模擬了一堆委托,實(shí)際上并不需要委托。這是直接翻譯的,可能比較書面語。
    //口語化的描述是,因?yàn)樵谶f歸解析中,為了正確的保持BeanDefinitionParserDelegate的引用關(guān)系,所以首先取出DefaultBeanDefinitionDocumentReader委托類暫存起來,然后創(chuàng)建一個(gè)新的委托類使用,最后再還原為之前的委托類。
    
    //獲取此DefaultBeanDefinitionDocumentReader的解析委托類
    BeanDefinitionParserDelegate parent = this.delegate;
    
    //利用現(xiàn)有的委托類(可能為null),創(chuàng)建一個(gè)新的委托類
    this.delegate = createDelegate(this.readerContext, root, parent);
    
    //預(yù)處理root,當(dāng)前是空實(shí)現(xiàn),可自行擴(kuò)展
    preProcessXml(root);
    //真正的處理root,并注冊(cè),詳細(xì)的見下一小節(jié)《parseBeanDefinitions》
    parseBeanDefinitions(root, this.delegate);
    //后處理root,當(dāng)前是空實(shí)現(xiàn),可自行擴(kuò)展
    postProcessXml(root);

    this.delegate = parent;
}
//輔助方法分析
//創(chuàng)建一個(gè)新的委托類BeanDefinitionParserDelegate
//
protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
    //目前createHelper返回的值都是null
    BeanDefinitionParserDelegate delegate = createHelper(readerContext, root, parentDelegate);
    //目前都會(huì)進(jìn)入此判斷內(nèi)
    if (delegate == null) {
        //創(chuàng)建一個(gè)新的BeanDefinitionParserDelegate
        delegate = new BeanDefinitionParserDelegate(readerContext, getEnvironment());
        //初始化,并通過readerContext分發(fā)一個(gè)開始注冊(cè)BeanDefinition的事件
        delegate.initDefaults(root, parentDelegate);
    }
    return delegate;
}
//BeanDefinitionParserDelegate.initDefaults
//默認(rèn)的文檔BeanDefinition
private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();

public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
    //給defaults設(shè)置初始值
    populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
    //分發(fā)一個(gè)defaultsRegistered事件
    this.readerContext.fireDefaultsRegistered(this.defaults);
}
//讀取中配置的屬性,并設(shè)置到defaults中
protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
    //設(shè)置 default-lazy-init ,
    //值為default時(shí),如果父節(jié)點(diǎn)不是null時(shí),繼承父節(jié)的屬性值,否則為false
    String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
        lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE;
    }
    defaults.setLazyInit(lazyInit);
    
    //設(shè)置 default-merge
    //值為default時(shí),如果父節(jié)點(diǎn)不是null時(shí),繼承父節(jié)的屬性值,否則為false
    String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(merge)) {
        merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE;
    }
    defaults.setMerge(merge);

    //設(shè)置 default-autowire
    //值為default時(shí),如果父節(jié)點(diǎn)不是null時(shí),繼承父節(jié)的屬性值,否則為no
    String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(autowire)) {
        autowire = parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE;
    }
    defaults.setAutowire(autowire);

    // don"t fall back to parentDefaults for dependency-check as it"s no
    // longer supported in  as of 3.0. Therefore, no nested 
    // would ever need to fall back to it.
    
    //設(shè)置 default-dependency-check ,不用檢查父節(jié)點(diǎn)的值了
    defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
    
    //設(shè)置 default-autowire-candidates
    if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
        defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
    }
    else if (parentDefaults != null) {
        defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
    }
    
    //設(shè)置 default-init-method
    if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
        defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
    }
    else if (parentDefaults != null) {
        defaults.setInitMethod(parentDefaults.getInitMethod());
    }
    
    //設(shè)置 default-destroy-method
    if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
        defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
    }
    else if (parentDefaults != null) {
        defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
    }
    //設(shè)置此DocumentDefaultsDefinition的元數(shù)據(jù)源
    defaults.setSource(this.readerContext.extractSource(root));
}

一個(gè)beans的圖示

parseBeanDefinitions
委托模式石錘了!

這里把root交給委托類delegate來處理,委托類delegate通過XmlReaderContext持有當(dāng)前的XmlBeanDefinitionReader、命名空間解析器、原始資源、事件分發(fā)器等,又直接持有環(huán)境的引用,而XmlBeanDefinitionReader又有BeanDefinitionRegistry的引用,可以說集萬千寵愛于一身,所以能力非常強(qiáng)大。我不得不畫個(gè)圖來表示一下敬意!

這里解析是的

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    //判斷root的xlmns是不是默認(rèn)的名稱空間,即"http://www.springframework.org/schema/beans"
    //這里是的
    if (delegate.isDefaultNamespace(root)) {
        //獲取全部子節(jié)點(diǎn)并遍歷
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            //如果節(jié)點(diǎn)是Element的話,這里主要是為了去除xml中無用的Text空節(jié)點(diǎn)
            //比如:__a____ 是有5個(gè)Node的
            //分別是:
            //1. 空白Text節(jié)點(diǎn)
            //2. 節(jié)點(diǎn)
            //3. 空白Text節(jié)點(diǎn)
            //4. 節(jié)點(diǎn)
            //5. 空白Text節(jié)點(diǎn)
            if (node instanceof Element) {
                Element ele = (Element) node;
                if (delegate.isDefaultNamespace(ele)) {
                    //解析有效節(jié)點(diǎn),處理不同的標(biāo)簽 import bean alias beans
                    parseDefaultElement(ele, delegate);
                }
                else {
                    delegate.parseCustomElement(ele);
                }
            }
            
        }
    }
    else {
        delegate.parseCustomElement(root);
    }
}
parseDefaultElement
處理import 、alias、bean、beans 這四種標(biāo)簽

其中最復(fù)雜的就是 beans 標(biāo)簽,他會(huì)導(dǎo)致程序遞歸到DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions方法,然后重復(fù)上面的所有步驟,有興趣的同學(xué)可以在< beans> 標(biāo)簽中嵌入一個(gè)< beans>,來研究下Spring是如何處理遞歸的。我這里就不再深入討論了。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    //處理 import 標(biāo)簽
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        importBeanDefinitionResource(ele);
    }
    // //處理 alias 標(biāo)簽
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
     //處理 bean 標(biāo)簽
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        processBeanDefinition(ele, delegate);
    }
     //處理 beans 標(biāo)簽
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse
        doRegisterBeanDefinitions(ele);
    }
}
processBeanDefinition
處理bean標(biāo)簽,先解析默認(rèn)命名空間中的屬性、和子標(biāo)簽

然后處理非默認(rèn)命名空間的標(biāo)簽

接著注冊(cè)BeanDefinition

最后發(fā)送一個(gè)BeanDefinition注冊(cè)事件

/**
     * Process the given bean element, parsing the bean definition
     * and registering it with the registry.
     */
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    //解析ele成BeanDefinition,并放入到BeanDefinitionHolder中
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    //如果bdHolder解析成功了就進(jìn)行
    if (bdHolder != null) {
        //解析非默認(rèn)命名空間的屬性
        //比如 http://www.springframework.org/schema/c 之類的標(biāo)簽
        //對(duì)應(yīng)的解析器也是就在springs.handlers文件中配置的,比如*/c的是org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            //向IOC中注冊(cè)該BeanDefiniton!!!
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name "" +
                                     bdHolder.getBeanName() + """, ele, ex);
        }
        //最后發(fā)送一個(gè)BeanDefinition注冊(cè)事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}
Element解析成BeanDefinition并放入到BeanDefinitionHolder中
//調(diào)用parseBeanDefinitionElement
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    return parseBeanDefinitionElement(ele, null);
}
//實(shí)際將Element解析成Beanfinition的方法
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    //獲取id屬性
    String id = ele.getAttribute(ID_ATTRIBUTE);
    //獲取name屬性
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
    //別名list
    List aliases = new ArrayList();
    
    //如果name屬性值不為空,按照 ,; 符號(hào)切分name,切分成一個(gè)name屬性,并放入到aliases中
    //這里看出bean的定義,可以定義多個(gè)name值,只要通過逗號(hào)或者分號(hào)分隔即可。
    if (StringUtils.hasLength(nameAttr)) {
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        aliases.addAll(Arrays.asList(nameArr));
    }
    
    //把beanName設(shè)置成id,
    String beanName = id;
    //如果沒有配置id,就把name中配置的第一個(gè)值作為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");
        }
    }
    //如果傳入的containingBean為null,就檢驗(yàn)beanName和aliases是不是已經(jīng)被占用了,
    //占用了就拋出一個(gè)異常BeanDefinitionParsingException,
    //這里傳入的containingBean就是null,所以一定要經(jīng)過里面檢查
    if (containingBean == null) {
        checkNameUniqueness(beanName, aliases, ele);
    }
    //把ele解析 beanDefinition,
    //其中此處的 beanDefinition的類型是GenericBeanDefinition
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    
    if (beanDefinition != null) {
        //如果beanName沒有的話,就使用BeanDefinitionReaderUtils.generateBeanName生成一個(gè)名字
          if (!StringUtils.hasText(beanName)) {
            try {
                if (containingBean != null) {
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                        beanDefinition, this.readerContext.getRegistry(), true);
                }
                else {
                    beanName = this.readerContext.generateBeanName(beanDefinition);
                    // Register an alias for the plain bean class name, if still possible,
                    // if the generator returned the class name plus a suffix.
                    // This is expected for Spring 1.2/2.0 backwards compatibility.
                    String beanClassName = beanDefinition.getBeanClassName();
                    if (beanClassName != null &&
                        beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                        !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                        aliases.add(beanClassName);
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Neither XML "id" nor "name" specified - " +
                                 "using generated bean name [" + beanName + "]");
                }
            }
            catch (Exception ex) {
                error(ex.getMessage(), ele);
                return null;
            }
        }
        String[] aliasesArray = StringUtils.toStringArray(aliases);
        // 用一個(gè)BeanDefinitionHolder ,把beanDefinition, beanName, aliasesArray封裝在一起然后返回
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
}
檢查name有沒有被使用
//檢查benaName、aliases是否被之前的bean占用
protected void checkNameUniqueness(String beanName, List aliases, Element beanElement) {
    String foundName = null;
    //判斷beanName是否被使用
    if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
        foundName = beanName;
    }
    //判斷是否aliases中有被占用的
    if (foundName == null) {
        foundName = (String) CollectionUtils.findFirstMatch(this.usedNames, aliases);
    }
    //如果找到了占用,就拋出異常
    if (foundName != null) {
        error("Bean name "" + foundName + "" is already used in this  element", beanElement);
    }
    //如果沒有發(fā)現(xiàn)占用,就把beanName和aliaes全部放入到usedNames中
    this.usedNames.add(beanName);
    this.usedNames.addAll(aliases);
}
Element解析成BeanDefinition
解析Bean中幾乎所有的屬性和一些配置的子標(biāo)簽,一個(gè)示例Bean標(biāo)簽的配置如圖

//Element解析成AbstractBeanDefinition
public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, BeanDefinition containingBean) {
    //把beanName壓入到棧parseState中
    this.parseState.push(new BeanEntry(beanName));

    String className = null;
    //獲取class屬性值,放入到className中
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }

    try {
        //如果有parent屬性,設(shè)置到parent中
        String parent = null;
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }
        //創(chuàng)建一個(gè)AbstractBeanDefinition,類型是GenericBeanDefinition
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);
        
        //解析ele的屬性,并設(shè)置到BeanDefinition中
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        
        //如果此bean標(biāo)簽有子標(biāo)簽description的話,就把description中的值設(shè)置到bd中
        //        message
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
        
        //解析子標(biāo)簽
        //        
        parseMetaElements(ele, bd);
        
        //解析 子標(biāo)簽,把配置的lookup-method放入到bd的methodOverrides中
        // 
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        
        //解析 replaced-method 標(biāo)簽
        //        
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
        
        //解析 構(gòu)造函數(shù)標(biāo)簽 
        //        
        parseConstructorArgElements(ele, bd);
        
        //解析 屬性標(biāo)簽 
        parsePropertyElements(ele, bd);
        
        //解析  標(biāo)簽
        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;
}
創(chuàng)建一個(gè)AbstractBeanDefinition
//利用className和parentName創(chuàng)建一個(gè)BeanDefinition
protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
    throws ClassNotFoundException {
    
    return BeanDefinitionReaderUtils.createBeanDefinition(
        parentName, className, this.readerContext.getBeanClassLoader());
}
//BeanDefinitionReaderUtils.createBeanDefinition方法創(chuàng)建的BeanDefinition的類型是GenericBeanDefinition
public static AbstractBeanDefinition createBeanDefinition(
    String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {
    //創(chuàng)建一個(gè)GenericBeanDefinition,設(shè)置ParentName,
    GenericBeanDefinition bd = new GenericBeanDefinition();
    bd.setParentName(parentName);
    //如果可以className和classLoader都有值的話,就把類Class加載出來,并設(shè)置到bd中
    //如果classLoder為空的話,就只設(shè)置一個(gè)className
    if (className != null) {
        if (classLoader != null) {
            //
            bd.setBeanClass(ClassUtils.forName(className, classLoader));
        }
        else {
            bd.setBeanClassName(className);
        }
    }
    return bd;
}
設(shè)置BeanDefinition的屬性
幾乎設(shè)置了一個(gè)BeanDefinition需要的全部屬性
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,                                                            BeanDefinition containingBean, AbstractBeanDefinition bd) {
    //解析spring2.x中的scope屬性
    //解析Spring1.x中的singleton屬性
    if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
        // Spring 2.x "scope" attribute
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
            error("Specify either "scope" or "singleton", not both", ele);
        }
    }
    else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
        // Spring 1.x "singleton" attribute
        bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
                    BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
    }
    else if (containingBean != null) {
        // Take default from containing bean in case of an inner bean definition.
        bd.setScope(containingBean.getScope());
    }

    //設(shè)置bd的 abstract 屬性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }
    
    //設(shè)置bd的 lazy-init 屬性
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
        lazyInit = this.defaults.getLazyInit();
    }
    bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
    
    //設(shè)置bd的 autowire 屬性
    String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
    bd.setAutowireMode(getAutowireMode(autowire));
    
    //設(shè)置bd的 dependency-check 屬性
    String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
    bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
    
    //設(shè)置bd的 depends-on 屬性
    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
        String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
        bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
    }
    
    //設(shè)置bd的 autowire-candidate 屬性
    String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
    if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
        String candidatePattern = this.defaults.getAutowireCandidates();
        if (candidatePattern != null) {
            String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
            bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
        }
    }
    else {
        bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
    }
    
    //設(shè)置bd的 primary 屬性
    if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
        bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
    }
    
   //設(shè)置bd的 init-method  屬性
    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
        String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
        if (!"".equals(initMethodName)) {
            bd.setInitMethodName(initMethodName);
        }
    }
    else {
        if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }
    }
    
     //設(shè)置bd的 destroy-method 屬性
    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
        String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
        if (!"".equals(destroyMethodName)) {
            bd.setDestroyMethodName(destroyMethodName);
        }
    }
    else {
        if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }
    }
    //設(shè)置bd的 factory-method 屬性
    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
        bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
    }
    //設(shè)置bd的 factory-bean 屬性
    if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
        bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
    }

    return bd;
}

BeanDefinition的繼承關(guān)系圖,可以看出GenericBeanDefinition的位置

寫的有點(diǎn)太多了,還有import標(biāo)簽和 alias標(biāo)簽的解析內(nèi)容,我放置《BeanDefinition注冊(cè)-下篇》中一起講解。

下篇中也會(huì)補(bǔ)充一些此文中關(guān)于注冊(cè)BeanDefintion的細(xì)節(jié)內(nèi)容。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/75344.html

相關(guān)文章

  • 仿照 Spring 實(shí)現(xiàn)簡(jiǎn)單的 IOC 和 AOP - 下篇

    摘要:在上文中,我實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的和容器。比如,我們所熟悉的就是在這里將切面邏輯織入相關(guān)中的。初始化的工作算是結(jié)束了,此時(shí)處于就緒狀態(tài),等待外部程序的調(diào)用。其中動(dòng)態(tài)代理只能代理實(shí)現(xiàn)了接口的對(duì)象,而動(dòng)態(tài)代理則無此限制。 1. 背景 本文承接上文,來繼續(xù)說說 IOC 和 AOP 的仿寫。在上文中,我實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的 IOC 和 AOP 容器。上文實(shí)現(xiàn)的 IOC 和 AOP 功能很單一,且 I...

    AlexTuan 評(píng)論0 收藏0
  • Spring解密 - 默認(rèn)標(biāo)簽的解析

    Spring是一個(gè)開源的設(shè)計(jì)層面框架,解決了業(yè)務(wù)邏輯層和其他各層的松耦合問題,將面向接口的編程思想貫穿整個(gè)系統(tǒng)應(yīng)用,同時(shí)它也是Java工作中必備技能之一... 前言 緊跟上篇 Spring解密 - XML解析 與 Bean注冊(cè) ,我們接著往下分析源碼 解密 在 Spring 的 XML 配置里面有兩大類聲明,一個(gè)是默認(rèn)的如 ,另一類就是自定義的如,兩種標(biāo)簽的解析方式差異是非常大的。parseBe...

    snowLu 評(píng)論0 收藏0
  • Spring-Mybatis運(yùn)行機(jī)制概括

    摘要:使用這個(gè)類庫(kù)中的類將會(huì)加載必要的工廠類和類。最終它并不會(huì)依賴于或來構(gòu)建應(yīng)用程序代碼。下面對(duì)各部分作用總結(jié)下。和無縫整合的機(jī)制和的認(rèn)識(shí)在講如何無縫整合進(jìn)之前,我們先認(rèn)識(shí)下和這兩個(gè)接口的作用。附上上篇博文地址原理概括。 前言 本篇是繼上篇MyBatis原理概括延伸的,所以如果有小伙伴還沒看上篇博文的話,可以先去看下,也不會(huì)浪費(fèi)大家太多的時(shí)間,因?yàn)楸酒獣?huì)結(jié)合到上篇敘述的相關(guān)內(nèi)容。 好,切入正...

    qieangel2013 評(píng)論0 收藏0
  • 追蹤解析Spring ioc啟動(dòng)源碼(1)

    摘要:主要過程為調(diào)用自身的另一個(gè)有參構(gòu)造器此處的即為本身此處的最終返回一個(gè)調(diào)用無參構(gòu)造器創(chuàng)建出來的對(duì)象參數(shù)非空效驗(yàn)保存創(chuàng)建一個(gè)用于注解解析器,后面會(huì)用到注冊(cè)需要用到的顧名思義,即為所處的環(huán)境,包括配置的讀取等。 零 前期準(zhǔn)備 0 FBI WARNING 文章異常啰嗦且繞彎。 1 版本 spring版本 : spring 5.1.2.RELEASE IDE : idea 2018.3 2 Be...

    Cheng_Gang 評(píng)論0 收藏0
  • 【Dubbo源碼閱讀系列】之 Dubbo XML 配置加載

    摘要:在介紹自定義標(biāo)簽解析前,先放一張圖幫助大家理解以下是如何從文件中解析并加載的。自定義標(biāo)簽比如的值為根據(jù)獲取到的,獲取對(duì)應(yīng)的對(duì)象。關(guān)于和加載先后順序的問題最后再集合一個(gè)小例子總結(jié)下吧當(dāng)我們先解析了元素時(shí),我們會(huì)遍歷所有已經(jīng)注冊(cè)注冊(cè)表中。 今天我們來談?wù)?Dubbo XML 配置相關(guān)內(nèi)容。關(guān)于這部分內(nèi)容我打算分為以下幾個(gè)部分進(jìn)行介紹: Dubbo XML Spring 自定義 XML 標(biāo)...

    wangshijun 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<