Spring|容器初始化流程及源碼分析


前言

了解Spring褐健、Spring IOC/DI缸血、Spring Bean,作者我沒有三顆心臟這三篇已經寫著很詳細了泛豪。
Spring學習(1)——快速入門
Spring(2)——Spring IoC 詳解
Spring(3)——裝配 Spring Bean 詳解

ApplicationContext

實例化Bean

Spring用來管理各個Bean稠诲,在程序中實例化bean通常會用到下面的代碼,有兩種方式:
java

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");

web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

體系結構及流程解析

體系結構流程圖


ApplicationContext體系結構圖
BeanFactory體系結構圖

流程解析

經過斷點調試就會知道诡曙,ClassPathXmlApplicationContext的初始化最終會指向AbstractApplicationContext的refresh()方法臀叙。

    // 完成IoC容器的創(chuàng)建及初始化工作
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            // STEP 1: 為context刷新做預處理
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // * STEP 2:讓子類刷新內部beanFactory 
            //      a) 創(chuàng)建IoC容器(DefaultListableBeanFactory--ConfigurableListableBeanFactory 的實現類)
            //      b) 加載解析XML文件(最終存儲到Document對象中)
            //      c) 讀取Document對象,并完成BeanDefinition的加載和注冊工作
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // STEP 3: 對IoC容器進行一些預處理(設置一些公共屬性)
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // STEP 4: 允許在AbstractApplicationContext的子類中對BeanFactory進行后置處理价卤,postProcessBeanFactory()這個方法是個空實現劝萤。
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // STEP 5: 調用BeanFactoryPostProcessor后置處理器處理BeanFactory實例(BeanDefinition)
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // STEP 6:
                //      a)  注冊BeanPostProcessor后置處理器
                //      b)BeanPostProcessors后置處理器用于攔截bean的創(chuàng)建,對創(chuàng)建后的bean實例進行處理
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // STEP 7: 初始化一些消息資源
                initMessageSource();

                // Initialize event multicaster for this context.
                // STEP 8: 
                //      a)  初始化應用事件廣播器
                //      b)  表明Spring內部基于事件機制
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                // STEP 9: 初始化一些特殊的bean荠雕,這個方法是空實現稳其,讓AbstractApplicationContext的子類重寫
                onRefresh();

                // Check for listener beans and register them.
                // STEP 10: 注冊一些監(jiān)聽器(ApplicationListener)
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // * STEP 11: 實例化剩余的單例bean(非懶加載方式)
                // 注意事項:Bean的IoC、DI和AOP都是發(fā)生在此步驟
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                // STEP 12: 完成刷新時炸卑,需要發(fā)布對應的事件
                finishRefresh();
            }

            catch (BeansException ex) { // 捕獲BeansException
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                // 銷毀已經創(chuàng)建的單例對象既鞠,
                destroyBeans();
               
                // Reset 'active' flag.
                //取消刷新,重置active標識(置為false)
                cancelRefresh(ex);
   
                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                // 重置Spring內核中的常用自檢緩存盖文,清空單例bean內緩存
                resetCommonCaches();
            }
        }
    }

創(chuàng)建BeanFactory流程源碼分析

// Tell the subclass to refresh the internal bean factory.
// STEP 2:
//      a) 創(chuàng)建IoC容器(DefaultListableBeanFactory)
//      b) 加載解析XML文件(最終存儲到Document對象中)
//      c) 讀取Document對象嘱蛋,并完成BeanDefinition的加載和注冊工作
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  • 進入AbstractApplication的obtainFreshBeanFactory()方法:
    用于創(chuàng)建一個新的IoC容器,這個IoC容器就是DefaultListableBeanFactory對象。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 主要是通過該方法完成IoC容器的刷新
        refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }
  • 進入AbstractRefreshableApplicationContext的refreshBeanFactory()方法:
    • 銷毀以前的容器
    • 創(chuàng)建新的IoC容器
    • 加載BeanDefinition對象注冊到IoC容器中
    @Override
    protected final void refreshBeanFactory() throws BeansException {
        // 如果之前有IoC容器洒敏,則銷毀
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 創(chuàng)建IoC容器龄恋,也就是DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 設置工廠的屬性:是否允許BeanDefinition覆蓋和是否允許循環(huán)依賴
            customizeBeanFactory(beanFactory);
            // * 調用載入BeanDefinition的方法,在當前類中只定義了抽象的loadBeanDefinitions方法凶伙,具體的實現調用子類容器
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }
  • 進入AbstractRefreshableApplicationContextcreateBeanFactory方法
protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }

加載BeanDefinition流程分析

  • 進入AbstractXmlApplicationContext的loadBeanDefinitions()方法:
    • 創(chuàng)建一個XmlBeanDefinitionReader郭毕,通過閱讀XML文件,真正完成BeanDefinition的加載和注冊
    • 配置XmlBeanDefinitionReader并進行初始化函荣。
    • 配置XmlBeanDefinitionReader并進行初始化显押。
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        // 創(chuàng)建一個BeanDefinition閱讀器,通過閱讀XML文件傻挂,真正完成BeanDefinition的加載和注冊
        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);
    
        // * 委托給BeanDefinition閱讀器去加載BeanDefinition
        loadBeanDefinitions(beanDefinitionReader);
    }


protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        // 獲取資源的定位
        // 這里getConfigResources是一個空實現乘碑,真正實現是調用子類的獲取資源定位的方法
        // 比如:ClassPathXmlApplicationContext中進行了實現
        //      而FileSystemXmlApplicationContext沒有使用該方法
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            // XML Bean讀取器調用其父類AbstractBeanDefinitionReader讀取定位的資源
            reader.loadBeanDefinitions(configResources);
        }
        // 如果子類中獲取的資源定位為空,則獲取FileSystemXmlApplicationContext構造方法中setConfigLocations方法設置的資源
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            // XML Bean讀取器調用其父類AbstractBeanDefinitionReader讀取定位的資源
            reader.loadBeanDefinitions(configLocations);
        }
    }
  • loadBeanDefinitions()
    (AbstractBeanDefinitionReader-->XmlBeanDefinitionReader)
    @Override
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        // 將讀入的XML資源進行特殊編碼處理
        return loadBeanDefinitions(new EncodedResource(resource));
    }

loadBeanDefinitions讀取XMl資源進行編碼處理,代碼有點長金拒,截取重要部分try()里面代碼

try {
            // 將資源文件轉為InputStream的IO流
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                // 從InputStream中得到XML的解析源
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                // 這里是具體的讀取過程
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
  • loadBeanDefinitions最終來到了XmlBeanDefinitionReader的doLoadBeanDefinitions方法:
    • 一個是對XML文件進行DOM解析
    • 一個是完成BeanDefinition對象的加載與注冊
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {
            // 通過DOM4J加載解析XML文件兽肤,最終形成Document對象
            Document doc = doLoadDocument(inputSource, resource);
            // 通過對Document對象的操作,完成BeanDefinition的加載和注冊工作
            return registerBeanDefinitions(doc, resource);
        }
        //省略一些catch語句
        catch (Throwable ex) {
            ......
        }
    }
  • 這里不去看處理DOM4J加載解析XML的流程
  • 進入XmlBeanDefinitionReaderregisterBeanDefinitions方法:
    • 創(chuàng)建DefaultBeanDefinitionDocumentReader用來解析Document對象绪抛。
    • 獲得容器中已注冊的BeanDefinition數量
    • 委托給DefaultBeanDefinitionDocumentReader來完成BeanDefinition的加載资铡、注冊工作。
    • 統(tǒng)計新注冊的BeanDefinition數量
public int  (Document doc, Resource resource) throws BeanDefinitionStoreException {
        // 創(chuàng)建BeanDefinitionDocumentReader來解析Document對象睦疫,完成BeanDefinition解析
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        // 獲得容器中已經注冊的BeanDefinition數量
        int countBefore = getRegistry().getBeanDefinitionCount();
        //解析過程入口害驹,BeanDefinitionDocumentReader只是個接口鞭呕,具體的實現過程在DefaultBeanDefinitionDocumentReader完成
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        // 統(tǒng)計新的的BeanDefinition數量
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }
  • 進入DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法:
    • 獲得Document的根元素<beans>標簽
    • 真正實現BeanDefinition解析和注冊工作
@Override
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        logger.debug("Loading bean definitions");
        // 獲得Document的根元素<beans>標簽
        Element root = doc.getDocumentElement();
        // 真正實現BeanDefinition解析和注冊工作
        doRegisterBeanDefinitions(root);
    }
  • 進入DefaultBeanDefinitionDocumentReader中的doRegisterBeanDefinitions方法:
    • 這里使用了委托模式蛤育,將具體的BeanDefinition解析工作交給了BeanDefinitionParserDelegate去完成
    • 在解析Bean定義之前,進行自定義的解析葫松,增強解析過程的可擴展性
    • 委托給BeanDefinitionParserDelegate,從Document的根元素開始進行BeanDefinition的解析
    • 在解析Bean定義之后瓦糕,進行自定義的解析,增加解析過程的可擴展性
/**
     * Register each bean definition within the given root {@code <beans/>} element.
     */
    protected void doRegisterBeanDefinitions(Element root) {
        
        // 這里使用了委托模式腋么,將具體的BeanDefinition解析工作交給了BeanDefinitionParserDelegate去完成
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(getReaderContext(), root, parent);

        // 判斷該根標簽是否包含http://www.springframework.org/schema/beans默認命名空間
        if (this.delegate.isDefaultNamespace(root)) {
            String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
                if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    if (logger.isInfoEnabled()) {
                        logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                                "] not matching: " + getReaderContext().getResource());
                    }
                    return;
                }
            }
        }
        // 在解析Bean定義之前咕娄,進行自定義的解析,增強解析過程的可擴展性珊擂,方法里面都是空實現
        preProcessXml(root);
        // 委托給BeanDefinitionParserDelegate,從Document的根元素開始進行BeanDefinition的解析
        parseBeanDefinitions(root, this.delegate);
        // 在解析Bean定義之后圣勒,進行自定義的解析,增加解析過程的可擴展性
        postProcessXml(root);

        this.delegate = parent;
    }

  • parseBeanDefinitions()解析文檔中跟層次的元素
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        // 加載的Document對象是否使用了Spring默認的XML命名空間(beans命名空間)
        if (delegate.isDefaultNamespace(root)) {
            // 獲取Document對象根元素的所有子節(jié)點(bean標簽摧扇、import標簽圣贸、alias標簽和其他自定義標簽context、aop等)
            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;
                    // bean標簽扛稽、import標簽吁峻、alias標簽,則使用默認解析規(guī)則
                    if (delegate.isDefaultNamespace(ele)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {//像context標簽、aop標簽用含、tx標簽矮慕,則使用用戶自定義的解析規(guī)則解析元素節(jié)點
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            // 如果不是默認的命名空間,則使用用戶自定義的解析規(guī)則解析元素節(jié)點
            delegate.parseCustomElement(root);
        }
    }
  • parseDefaultElement()自定義標簽讀取
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>標簽
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            // 遞歸調用
            doRegisterBeanDefinitions(ele);
        }
    }
  • processBeanDefinition()解析自定義標簽
/**
     * Process the given bean element, parsing the bean definition
     * and registering it with the registry.
     */
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // 解析<bean>標簽啄骇,獲取BeanDefinition
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            // 如果需要痴鳄,則裝飾BeanDefinition對象
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // Register the final decorated instance.
                // 注冊最終的BeanDefinition到BeanDefinitionRegistry(DefaultListableBeanFactory)
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }
  • 進入BeanDefinitionParserDelegate中的parseBeanDefinitionElement方法:
    • 獲取bean的id和name
    • 通過這個方法實現解析<bean>標簽,獲取BeanDefinition
    • 將BeanDefinition對象和BeanName封裝到BeanDefinitionHolder對象中
@Nullable
    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        // 獲取bean的id
        String id = ele.getAttribute(ID_ATTRIBUTE);
        // 獲取bean的name
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

        List<String> aliases = new ArrayList<>();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            aliases.addAll(Arrays.asList(nameArr));
        }

        String beanName = id;
        if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
            beanName = aliases.remove(0);
            if (logger.isDebugEnabled()) {
                logger.debug("No XML 'id' specified - using '" + beanName +
                        "' as bean name and " + aliases + " as aliases");
            }
        }

        if (containingBean == null) {
            // 檢查bean的id或者name是否唯一
            checkNameUniqueness(beanName, aliases, ele);
        }
        // 解析<bean>標簽缸夹,獲取BeanDefinition對象
        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
                        beanName = BeanDefinitionReaderUtils.generateBeanName(
                                beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {
                        beanName = this.readerContext.generateBeanName(beanDefinition);
                        // Register an alias for the plain bean class name, if still possible,
                        // if the generator returned the class name plus a suffix.
                        // This is expected for Spring 1.2/2.0 backwards compatibility.
                        String beanClassName = beanDefinition.getBeanClassName();
                        if (beanClassName != null &&
                                beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                                !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                            aliases.add(beanClassName);
                        }
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Neither XML 'id' nor 'name' specified - " +
                                "using generated bean name [" + beanName + "]");
                    }
                }
                catch (Exception ex) {
                    error(ex.getMessage(), ele);
                    return null;
                }
            }
            String[] aliasesArray = StringUtils.toStringArray(aliases);
            // 將BeanDefinition對象和BeanName封裝到BeanDefinitionHolder對象中
            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        }

        return null;
    }

  • 通過parseBeanDefinitionElement()方法解析bean標簽
    通過parseBeanDefinitionAttributes()解析bean標簽屬性
    /**
     * Parse the bean definition itself, without regard to name or aliases. May return
     * {@code null} if problems occurred during the parsing of the bean definition.
     */
    @Nullable
    public AbstractBeanDefinition parseBeanDefinitionElement(
            Element ele, String beanName, @Nullable BeanDefinition containingBean) {

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

        String className = null;
        // 獲取bean標簽的class屬性
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
        }
        String parent = null;
        // 獲取bean標簽的parent屬性
        if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
            parent = ele.getAttribute(PARENT_ATTRIBUTE);
        }

        try {
            // 創(chuàng)建BeanDefinition對象GenericBeanDefinition
            AbstractBeanDefinition bd = createBeanDefinition(className, parent);
            
            // 解析<bean>標簽的屬性
            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            /** 解析<bean>標簽的子標簽  --- begin**/
            // 解析<description>標簽
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
            // 解析<meta>標簽
            parseMetaElements(ele, bd);
            // 解析<lookup-method>標簽
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            // 解析<replaced-method>標簽
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            // 解析<constructor-arg>標簽
            parseConstructorArgElements(ele, bd);
            // 解析<property>標簽
            parsePropertyElements(ele, bd);
            // 解析<qualifier>標簽
            parseQualifierElements(ele, bd);
            /** 解析<bean>標簽的子標簽  --- end**/

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

    /**
     * Apply the attributes of the given bean element to the given bean * definition.
     * @param ele bean declaration element
     * @param beanName bean name
     * @param containingBean containing bean definition
     * @return a bean definition initialized according to the bean element attributes
     */
    public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
            @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {

        // 解析<bean>標簽的singleton屬性
        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
            error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
        }
        // 解析<bean>標簽的scope屬性
        else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
            bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        }
        else if (containingBean != null) {
            // Take default from containing bean in case of an inner bean definition.
            bd.setScope(containingBean.getScope());
        }

        // 解析<bean>標簽的abstract屬性
        if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
            bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
        }
        // 解析<bean>標簽的lazy-init屬性
        String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
        if (DEFAULT_VALUE.equals(lazyInit)) {
            lazyInit = this.defaults.getLazyInit();
        }
        bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

        // 解析<bean>標簽的autowire屬性
        String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
        bd.setAutowireMode(getAutowireMode(autowire));

        // 解析<bean>標簽的depends-on屬性
        if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
            String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
            bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
        }

        // 解析<bean>標簽的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));
        }

        // 解析<bean>標簽的primary屬性
        if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
            bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
        }

        // 解析<bean>標簽的init-method屬性
        if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
            String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
            bd.setInitMethodName(initMethodName);
        }
        else if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }

        // 解析<bean>標簽的destroy-method屬性
        if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
            String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
            bd.setDestroyMethodName(destroyMethodName);
        }
        else if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }

        // 解析<bean>標簽的factory-method屬性
        if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
            bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
        }
        // 解析<bean>標簽的factory-bean屬性
        if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
            bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
        }

        return bd;
    }

實例化剩余的單例Bean(非懶加載模式)

finishBeanFactoryInitialization方法解析(STEP 11)

  • 進入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.
        // 實例化剩余的單例bean(非懶加載方式)
        // 注意事項:Bean的IoC、DI和AOP都是發(fā)生在此步驟
        beanFactory.preInstantiateSingletons();
    }
  • 進入DefaultListableBeanFactory中的preInstantiateSingletons()方法:
    • 通過beanName獲取bean實例明未,如果獲取到的實例不滿足條件就看最后一行getBean(beanName)槽华;
    • 核心代碼 getBean(beanName);
@Override
    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.
        // 得到Bean定義名稱
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        // 觸發(fā)所有非懶加載方式的單例bean的創(chuàng)建
        for (String beanName : beanNames) {
        // 遍歷得到對應的bean定義信息
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 如果bean不是抽象的,而且是單例的趟妥,同時還不是懶加載的猫态,則進行下面的操作
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 如果bean是一個工廠bean,則走下面的方法 披摄,和普通bean區(qū)別就是還可以生成bean
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else { // 普通bean走下面的方法
                    getBean(beanName);
                }
            }
        }
  • 進入AbstractBeanFactory通過doGetBean()方法獲取Bean的實例
    • 通過getSingleton(beanName)方法去緩存中獲取單例Bean(第一次初始化亲雪,緩存中不存在)
    • 如果取出來的bean實例是factoryBean的實例,則需要從factoryBean中產生一個Bean對象
    • 根據當前的beanfactory獲取父一級的beanFactory,遞歸查找我們需要的Bean(Bean是早不到的疚膊,第一次初始化)
    • 獲取實例化Bean的BeanDefinition對象
    • 重要义辕,我們一般是單例Bean,用匿名內部類的寫法寓盗,創(chuàng)建單例BeanBean
@Override
    public Object getBean(String name) throws BeansException {
        // 獲取Bean的實例
        return doGetBean(name, null, null, false);
    }


@SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        // 獲取bean名稱
        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        // 從緩存中獲取單例bean
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) { //如果獲取到單例bean灌砖,則走下面代碼
            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實例是FactoryBean的Bean實例,則需要從FactoryBean實例中產生一個對象實例傀蚌。
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {//如果沒有獲取到單例bean基显,則走下面代碼
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            
            // 如果原型模式的Bean發(fā)生循環(huán)引用,則直接不處理善炫,拋出異常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            ////獲取父類的beanfactory
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                // 獲取要實例化的bean的BeanDefinition對象
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 檢查該BeanDefinition對象對應的Bean是否是抽象的
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                // 如果是單例的Bean撩幽,請下面的代碼
                if (mbd.isSingleton()) {                    //匿名內部類的寫法
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // * 創(chuàng)建單例Bean的主要方法
                            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);
                }
************省略中間代碼
                      return (T) bean;
}
  • 通過DefaultSingletonBeanRegistry中的getSingleton()從緩存中獲取單例bean
@Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 從一級緩存中獲取單例對象
        Object singletonObject = this.singletonObjects.get(beanName);
        // isSingletonCurrentlyInCreation : 
        //      判斷當前單例bean是否正在創(chuàng)建中,也就是沒有初始化完成
        //      比如A的構造器依賴了B對象所以得先去創(chuàng)建B對象箩艺,或者在A的populateBean過程中依賴了B對象窜醉,得先去創(chuàng)建B對象
        //      這時的A就是處于創(chuàng)建中的狀態(tài)。
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                // 從二級緩存中獲取單例bean
                singletonObject = this.earlySingletonObjects.get(beanName);
                // allowEarlyReference 
                //      是否允許從singletonFactories中通過getObject拿到對象
                if (singletonObject == null && allowEarlyReference) {
                    // 從三級緩存中獲取單例bean
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 通過單例工廠獲取單例bean
                        singletonObject = singletonFactory.getObject();
                        // 從三級緩存移動到了二級緩存
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

  • 分析一下createBean()方法:
    • 處理方法覆蓋艺谆,也就是方法重寫
    • 獲取BeanPostProcessor代理對象榨惰,beanPostProcessor是可以臨時修改bean的,它的優(yōu)先級高于正常實例化Bean擂涛,beanPostProcessor如果能返回就直接返回了
    • 完成Bean的實例化創(chuàng)建doCreateBean()
@Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
省略一些代碼**********************
// 處理方法覆蓋
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }
}
*********************************
try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // 獲取BeanPostProcessor代理對象
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }

*****
    try {
            // 完成Bean實例的創(chuàng)建(實例化读串、填充屬性聊记、初始化)
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
****

doCreateBean完成Bean實例的創(chuàng)建(實例化、填充屬性恢暖、初始化)

  • bean初始化第一步排监,默認調用無參數構造實例化bean
  • bean初始化第二步,填充屬性(DI依賴注入發(fā)生在此步驟)
  • bean初始化第三步杰捂,調用初始化方法舆床,完成bean的初始化操作AOP發(fā)生在此步驟)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        // 用BeanWrapper來持有創(chuàng)建出來的Bean對象
        BeanWrapper instanceWrapper = null;
        // 如果是單例的話,則先把緩存中的bean清除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // bean初始化第一步:默認調用無參構造實例化Bean
        // 構造參數依賴注入嫁佳,就是發(fā)生在這一步
                // 為了下一步populateBean方法的屬性注入做準備
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 實例化后的Bean對象
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        // 解決循環(huán)依賴的關鍵步驟
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        // 如果需要提前暴露單例Bean挨队,則將該Bean放入三級緩存中
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 將剛創(chuàng)建的bean放入三級緩存中singleFactories(key是beanName,value是FactoryBean)
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            // bean初始化第二步:填充屬性(DI依賴注入發(fā)生在此步驟)
            populateBean(beanName, mbd, instanceWrapper);
            // bean初始化第三步:調用初始化方法蒿往,完成bean的初始化操作(AOP發(fā)生在此步驟)
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
******************************************
}

屬性注入

  • 通過AbstractAutowireCapableBeanFactory中populateBean()方法完成
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
/******************省略中間代碼***********************/
        // 完成依賴注入
        // PropertyValues pvs:待依賴的屬性值集合
        // BeanWrapper bw :實例化后的Bean的包裝對象
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
}
  • 這個有深了....盛垦,跟進去applyPropertyValues()方法,將PropertyValue一個一個賦值到一個新的List里面去瓤漏,起名為deepCopy 腾夯,最后setPropertyValue()
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        // Create a deep copy, resolving any references for values.
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
                else if (convertible && originalValue instanceof TypedStringValue &&
                        !((TypedStringValue) originalValue).isDynamic() &&
                        !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                    pv.setConvertedValue(convertedValue);
                    deepCopy.add(pv);
                }
                else {
                    resolveNecessary = true;
                    deepCopy.add(new PropertyValue(pv, convertedValue));
                }
            }
        }
        if (mpvs != null && !resolveNecessary) {
            mpvs.setConverted();
        }

        // 完成依賴注入
        // Set our (possibly massaged) deep copy.
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        
}
  • 通過AbstractPropertyAccessor中的 setPropertyValues()
    • 遍歷前面的deepCopy,每拿到一個PropertyValue蔬充,然后再setPropertyValue
@Override
    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
            throws BeansException {

        List<PropertyAccessException> propertyAccessExceptions = null;
        List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?
                ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
        for (PropertyValue pv : propertyValues) {
            try {
                // This method may throw any BeansException, which won't be caught
                // here, if there is a critical failure such as no matching field.
                // We can attempt to deal only with less serious exceptions.
                
                // 依賴屬性注入
                setPropertyValue(pv);
            }
            catch (NotWritablePropertyException ex) {
                if (!ignoreUnknown) {
                    throw ex;
                }
                // Otherwise, just ignore it and continue...
            }
            catch (NullValueInNestedPathException ex) {
                if (!ignoreInvalid) {
                    throw ex;
                }
                // Otherwise, just ignore it and continue...
            }
            catch (PropertyAccessException ex) {
                if (propertyAccessExceptions == null) {
                    propertyAccessExceptions = new LinkedList<>();
                }
                propertyAccessExceptions.add(ex);
            }
        }
  • AbstractNestablePropertyAccessor
    執(zhí)行上面的setPropertyValue方法
    @Override
    public void setPropertyValue(PropertyValue pv) throws BeansException {
        PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
        if (tokens == null) {
            String propertyName = pv.getName();
            AbstractNestablePropertyAccessor nestedPa;
            try {
                nestedPa = getPropertyAccessorForPropertyPath(propertyName);
            }
            catch (NotReadablePropertyException ex) {
                throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
                        "Nested property in path '" + propertyName + "' does not exist", ex);
            }
            tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
            if (nestedPa == this) {
                pv.getOriginalPropertyValue().resolvedTokens = tokens;
            }
            // 屬性注入
            nestedPa.setPropertyValue(tokens, pv);
        }
        else {
            // 屬性注入
            setPropertyValue(tokens, pv);
        }
    }
  • 進入 setPropertyValue方法的最后一步
    protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        // tokens.keys只要不為空蝶俱,則表示要依賴的屬性是集合類型的屬性
        if (tokens.keys != null) {
            processKeyedProperty(tokens, pv);
        }
        else { // 設置非集合類型的屬性
            processLocalProperty(tokens, pv);
        }
    }

  • 進入processLocalProperty()方法
    • 獲取屬性的處理器PropertyHandler
    • 通過PropertyHandler完成依賴注入
    private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
        // 獲取屬性處理器
        PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
        if (ph == null || !ph.isWritable()) {
            if (pv.isOptional()) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Ignoring optional value for property '" + tokens.actualName +
                            "' - property not found on bean class [" + getRootClass().getName() + "]");
                }
                return;
            }
            else {
                throw createNotWritablePropertyException(tokens.canonicalName);
            }
        }

        Object oldValue = null;
        try {
            // 獲取原始的值
            Object originalValue = pv.getValue();
            Object valueToApply = originalValue;
            if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
                if (pv.isConverted()) {
                    valueToApply = pv.getConvertedValue();
                }
                else {
                    if (isExtractOldValueForEditor() && ph.isReadable()) {
                        try {
                            oldValue = ph.getValue();
                        }
                        catch (Exception ex) {
                            if (ex instanceof PrivilegedActionException) {
                                ex = ((PrivilegedActionException) ex).getException();
                            }
                            if (logger.isDebugEnabled()) {
                                logger.debug("Could not read previous value of property '" +
                                        this.nestedPath + tokens.canonicalName + "'", ex);
                            }
                        }
                    }
                    valueToApply = convertForProperty(
                            tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
                }
                pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
            }
            // 通過PropertyHandler去完成依賴注入
            ph.setValue(valueToApply);
        }
        catch (TypeMismatchException ex) {
            throw ex;
        }
        catch (InvocationTargetException ex) {
            PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
                    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
            if (ex.getTargetException() instanceof ClassCastException) {
                throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
            }
            else {
                Throwable cause = ex.getTargetException();
                if (cause instanceof UndeclaredThrowableException) {
                    // May happen e.g. with Groovy-generated methods
                    cause = cause.getCause();
                }
                throw new MethodInvocationException(propertyChangeEvent, cause);
            }
        }
        catch (Exception ex) {
            PropertyChangeEvent pce = new PropertyChangeEvent(
                    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
            throw new MethodInvocationException(pce, ex);
        }
    }

  • BeanWrapperImpl
    通過屬性處理器setValue()完成依賴工作
@Override
        public void setValue(final @Nullable Object value) throws Exception {
            // 使用JDK 內省技術,獲取對指定屬性的setter方法的獲取(writeMethod)
            final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
                    ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
                    this.pd.getWriteMethod());
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    ReflectionUtils.makeAccessible(writeMethod);
                    return null;
                });
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                            writeMethod.invoke(getWrappedInstance(), value), acc);
                }
                catch (PrivilegedActionException ex) {
                    throw ex.getException();
                }
            }
            else {
                // 通過反射工具類饥漫,對setter方法開啟暴力破解(私有的方法榨呆,我也可以調用)
                ReflectionUtils.makeAccessible(writeMethod);
                // 利用反射技術,去執(zhí)行對應的setter方法(不一定真正擁有該屬性庸队,但是一定要有對應的setter方法)
                writeMethod.invoke(getWrappedInstance(), value);
                // method.invoke(obj,args);
            }
        }

Aware注入

// bean初始化第三步:調用初始化方法积蜻,完成bean的初始化操作(AOP發(fā)生在此步驟)
exposedObject = initializeBean(beanName, exposedObject, mbd);
}

  • AbstractAutowireCapableBeanFactory
    在使用Spring的時候,我們將自己的Bean實現BeanNameAware接口和BeanFactoryAware接口等皿哨,依賴容器幫我們注入當前Bean的名稱或者Bean工廠浅侨。進入上面的initializeBean()方法纽谒。
    • 應用BeanPostProcessor的postProcessBeforeInitialization方法在初始化之前被調用
    • 執(zhí)行初始化方法(先調用InitializingBean的afterPropertiesSet证膨,再調用init-method屬性指定的初始化方法)
    • 應用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理對象生成)在初始化之后被調用
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // 判斷beanName是哪個接口的的實現類如果bean是BeanNameAware接口的實現類會調用setBeanName方法、如果bean是BeanClassLoaderAware接口的實現類會調用setBeanClassLoader方法鼓黔、如果是BeanFactoryAware接口的實現類會調用setBeanFactory方法央勒,注入對應的屬性值。
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //應用BeanPostProcessor的postProcessBeforeInitialization方法
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            //執(zhí)行初始化方法(先調用InitializingBean的afterPropertiesSet澳化,再調用init-method屬性指定的初始化方法)
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //應用BeanPostProcessor的postProcessAfterInitialization方法(AOP代理對象生成)
            // AOP是等著對象創(chuàng)建完畢崔步,在進行增強
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
  • 調用初始化方法invokeInitMethods()
    • 判斷是否是InitializingBean接口的實現類,如果是縣初始化InitializingBean
    • 如果不是則調用InitializingBean接口中的afterPropertiesSet方法
    • 然后再初始化<bean>標簽對應的init-method屬性中的方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {

        boolean isInitializingBean = (bean instanceof InitializingBean);
        // 如果是InitializingBean接口的實現類缎谷,則先初始化InitializingBean的實現類
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                // 調用InitializingBean接口的afterPropertiesSet方法
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        // 然后再初始化<bean>標簽對應的init-method屬性中的方法
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                // 調用自定義的初始化方法
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
  • 在initializeBean方法中調用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法
    • 在初始化Bean的時候都會調用每一個配置的BeanPostProcessor的方法
@Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

補充:
Spring源碼系列:BeanWrapper

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末井濒,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌瑞你,老刑警劉巖酪惭,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異者甲,居然都是意外死亡春感,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門虏缸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲫懒,“玉大人,你說我怎么就攤上這事刽辙】遥” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵宰缤,是天一觀的道長谦秧。 經常有香客問我,道長撵溃,這世上最難降的妖魔是什么疚鲤? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮缘挑,結果婚禮上集歇,老公的妹妹穿的比我還像新娘。我一直安慰自己语淘,他們只是感情好诲宇,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惶翻,像睡著了一般姑蓝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吕粗,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天纺荧,我揣著相機與錄音,去河邊找鬼颅筋。 笑死宙暇,一個胖子當著我的面吹牛,可吹牛的內容都是我干的议泵。 我是一名探鬼主播占贫,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼先口!你這毒婦竟也來了型奥?” 一聲冷哼從身側響起瞳收,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厢汹,沒想到半個月后缎讼,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡坑匠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年血崭,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厘灼。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡夹纫,死狀恐怖,靈堂內的尸體忽然破棺而出设凹,到底是詐尸還是另有隱情舰讹,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布闪朱,位于F島的核電站月匣,受9級特大地震影響,放射性物質發(fā)生泄漏奋姿。R本人自食惡果不足惜锄开,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望称诗。 院中可真熱鬧萍悴,春花似錦、人聲如沸寓免。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袜香。三九已至撕予,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜈首,已是汗流浹背实抡。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留疾就,地道東北人澜术。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像猬腰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子猜敢,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內容

  • 本文是我自己在秋招復習時的讀書筆記姑荷,整理的知識點盒延,也是為了防止忘記,尊重勞動成果鼠冕,轉載注明出處哦添寺!如果你也喜歡,那...
    波波波先森閱讀 12,276評論 6 86
  • 本文較長(建議閱讀時間30min) 所謂的將組件注入容器中包含兩方面懈费,一是組件最先肯定是通過"org.xxxx.C...
    Sophie12138閱讀 4,943評論 2 12
  • 寫下這個標題源于身邊有一個同事感慨:為什么我這么努力工作憎乙,卻沒有她那么好命票罐。至于同事為什么這么說,不是樓主要講的重...
    甜甜圈少年閱讀 1,418評論 0 1
  • 朱子在溪山書院的時候泞边,和當地人禮尚往來该押,相處根好 元宵佳節(jié).朱子在溪山書院宴請門人和附近的老百姓.奇怪的 是,客人...
    寧德城市資訊閱讀 486評論 0 51
  • day20#每一個關鍵詞#時間 感覺時間不夠阵谚,是什么原因蚕礼?我打算記錄一下自己每天的時間,到底做了些什么梢什?怎樣就...
    曼頭閱讀 120評論 0 0