成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring IoC源碼執(zhí)行流程解析

ccj659 / 766人閱讀

摘要:這篇文章是我學(xué)習(xí)分析其源碼時(shí)總結(jié)的,其目的并非是完全理解源碼信息,但是根據(jù)容器如何從文件到的實(shí)例初始化進(jìn)行了一個(gè)流程的梳理,希望可以對(duì)大家理解源碼有一定的幫助。

這篇文章是我學(xué)習(xí)spring IoC 分析其源碼時(shí)總結(jié)的,其目的并非是完全理解源碼信息,但是根據(jù)spring IoC 容器如何從xml文件到bean的實(shí)例初始化進(jìn)行了一個(gè)流程的梳理,希望可以對(duì)大家理解源碼有一定的幫助。話不多少,我們直接來(lái)看。

這里,我是用ApplicationContext來(lái)進(jìn)行介紹,畢竟項(xiàng)目中大部分還是使用的這個(gè)容器。容器啟動(dòng)的入口我們可以從AbstractApplicationContext類的refresh方法看起。
Spring IoC容器對(duì)Bean定義資源的載入是從refresh()函數(shù)開始的,refresh()是一個(gè)模板方法,refresh()方法的作用是:在創(chuàng)建IoC容器前,如果已經(jīng)有容器存在,則需要把已有的容器銷毀和關(guān)閉,以保證在refresh之后使用的是新建立起來(lái)的IoC容器。refresh的作用類似于對(duì)IoC容器的重啟,在新建立好的容器中對(duì)容器進(jìn)行初始化,對(duì)Bean定義資源進(jìn)行載入。

refresh

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset "active" flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }
        }
    }

上邊有兩個(gè)很重要的方法:

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
這個(gè)方法就是根據(jù)Xml配置文件解析Bean的信息生成BeanDifinition,然后注冊(cè)到BeanDefinitionRegistry中,即bean信息的裝載注冊(cè)階段

beanFactory.preInstantiateSingletons();
這個(gè)方法看其注釋我們就可以理解,它是實(shí)例化所有非懶加載的單例bean。

AbstractApplicationContext的obtainFreshBeanFactory()方法調(diào)用子類容器的refreshBeanFactory()方法,啟動(dòng)容器載入Bean定義資源文件的過(guò)程,代碼如下:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {  
        //這里使用了委派設(shè)計(jì)模式,父類定義了抽象的refreshBeanFactory()方法,具體實(shí)現(xiàn)調(diào)用子類容器的refreshBeanFactory()方法
         refreshBeanFactory();  
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();  
        if (logger.isDebugEnabled()) {  
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);  
        }  
        return beanFactory;  
    } 

AbstractApplicationContext類中只抽象定義了refreshBeanFactory()方法,容器真正調(diào)用的是其子類AbstractRefreshableApplicationContext實(shí)現(xiàn)的 refreshBeanFactory()方法。代碼如下:

protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

在這個(gè)方法中,先判斷BeanFactory是否存在,如果存在則先銷毀beans并關(guān)閉beanFactory,接著創(chuàng)建DefaultListableBeanFactory,并調(diào)用loadBeanDefinitions(beanFactory)裝載bean定義。

我們?cè)谄渥宇怉bstractXmlApplicationContext最終可以看到下面這個(gè)方法,此方法就是真正從XML文件中讀取并解析Bean的信息,放在對(duì)應(yīng)的BeanDefinition中

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context"s
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // Allow a subclass to provide custom initialization of the reader,
        // then proceed with actually loading the bean definitions.
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }

再看preInstantiateSingletons()

public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isInfoEnabled()) {
            this.logger.info("Pre-instantiating singletons in " + this);
        }
        List beanNames;
        synchronized (this.beanDefinitionMap) {
            // 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.
            beanNames = new ArrayList(this.beanDefinitionNames);
        }
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
                            public Boolean run() {
                                return ((SmartFactoryBean) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
    }

其中我們需要關(guān)注getBean(beanName)這個(gè)方法,此方法中進(jìn)行了bean的實(shí)例化和初始化;我們可以進(jìn)入這個(gè)方法中,看到doGetBean() 這個(gè)方法

protected  T doGetBean(
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
            throws BeansException {
            ... ...  
            //這一部分是先從緩存中獲取對(duì)應(yīng)的bean;如果有的話,返回緩存中的單例bean;
            Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean "" + beanName +
                            "" that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean "" + beanName + """);
                }
            }
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        
        else {
        
        ... ...
        /**
            * Return a merged RootBeanDefinition, traversing the parent bean definition
            * if the specified bean corresponds to a child bean definition.
            */
        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dependsOnBean : dependsOn) {
                    getBean(dependsOnBean);
                    registerDependentBean(dependsOnBean, beanName);
                }
            }

            // Create bean instance.
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
        }
            }

上邊的代碼中,我們需要關(guān)心的是

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
獲取到對(duì)應(yīng)beanName的BeanDefinition,這里顯然是做了些包裝(RootBeanDefinition);

由于在項(xiàng)目中,絕大部分bean都是單例的,所以我們只關(guān)心單例類型的bean的創(chuàng)建

if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

注意,這里重新 實(shí)現(xiàn)了ObjectFactory中的getObject()方法,這個(gè)對(duì)下面的理解有很大幫助。我們先進(jìn)入getSingleton()方法中

public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
        Assert.notNull(beanName, ""beanName" must not be null");
        synchronized (this.singletonObjects) {
            //從緩存中獲取對(duì)應(yīng)的bean
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                if (this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while the singletons of this factory are in destruction " +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Creating shared instance of singleton bean "" + beanName + """);
                }
                beforeSingletonCreation(beanName);
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }
                try {
                    singletonObject = singletonFactory.getObject();
                }
                catch (BeanCreationException ex) {
                    if (recordSuppressedExceptions) {
                        for (Exception suppressedException : this.suppressedExceptions) {
                            ex.addRelatedCause(suppressedException);
                        }
                    }
                    throw ex;
                }
                finally {
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }
                    afterSingletonCreation(beanName);
                }
                //在這里將實(shí)例化的bean放入容器中;
                addSingleton(beanName, singletonObject);
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }
    }

這里邊我們需要關(guān)注的有

beforeSingletonCreation(beanName);
從名稱我們大概可以猜出來(lái)這個(gè)方法的一些作用:在單例bean創(chuàng)建之前所要做的事;

singletonObject = singletonFactory.getObject();
看到這里,你會(huì)想到什么?前面所說(shuō)的在上一層重新實(shí)現(xiàn)了次方法,所以這一塊得注意,它執(zhí)行的是重新實(shí)現(xiàn)后的方法,等下具體分析。

afterSingletonCreation(beanName);
對(duì)應(yīng)beforeSingletonCreation,這個(gè)就是在單例bean創(chuàng)建之后所要做的事;

接下來(lái),我們回頭看一下重新實(shí)現(xiàn)的singletonFactory.getObject()里調(diào)用了createBean(beanName, mbd, args);

我們進(jìn)入createBean(beanName, mbd, args)

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

        if (logger.isDebugEnabled()) {
            logger.debug("Creating instance of bean "" + beanName + """);
        }
        // Make sure bean class is actually resolved at this point.
        resolveBeanClass(mbd, beanName);

        // Prepare method overrides.
        try {
            mbd.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            Object bean = resolveBeforeInstantiation(beanName, mbd);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        Object beanInstance = doCreateBean(beanName, mbd, args);
        if (logger.isDebugEnabled()) {
            logger.debug("Finished creating instance of bean "" + beanName + """);
        }
        return beanInstance;
    }

在這里,我們可以看到

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

在這個(gè)方法中進(jìn)行備案的實(shí)例化(有人這時(shí)候會(huì)說(shuō),怎么這么就還沒(méi)有看到真正的bean實(shí)例化,沒(méi)辦法,spring自己還要實(shí)現(xiàn)自己的一些東西,這些我們不關(guān)注,但是不代表沒(méi)有必要,所以耐心看下去吧)

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
        //這個(gè)類將作為最終的bean單例放入容器中
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }

        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        //處理循環(huán)依賴的問(wèn)題
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean "" + beanName +
                        "" to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, new ObjectFactory() {
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

// Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }
        
... ... 

}

此方法較長(zhǎng),我們只需要關(guān)心我們需要關(guān)心的。

BeanWrapper instanceWrapper = null;
此類將作為最終的單例bean放入容器中,這個(gè)類將會(huì)是對(duì)應(yīng)bean的一個(gè)封裝;

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
允許其他修改beanDefinition,這主要是允許其他組件提供xml不能提供的信息。如使用Annotation增強(qiáng)Bean定義等。這通過(guò)類ergedBeanDefinitionPostProcessor來(lái)完成,如果容器中提供了此類實(shí)現(xiàn),則會(huì)調(diào)用進(jìn)行bean增強(qiáng)。

populateBean(beanName, mbd, instanceWrapper);
此方法里是利用InstantiationAwareBeanPostProcessor將bean進(jìn)行填充,以及autowire標(biāo)簽的處理

exposedObject = initializeBean(beanName, exposedObject, mbd);
重頭戲來(lái)了,這個(gè)才是我們最要關(guān)心的,在里邊會(huì)進(jìn)行bean的實(shí)例化和初始化

進(jìn)入initializeBean

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            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()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

這里邊有三個(gè)重要的方法

invokeAwareMethods(beanName, bean);
查看該bean是否實(shí)現(xiàn)了相關(guān)的Aware接口,如果有,將其進(jìn)行裝配;

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

invokeInitMethods(beanName, wrappedBean, mbd);
這里利用Java反射機(jī)制將bean對(duì)應(yīng)的beanDefinition信息進(jìn)行設(shè)置;

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

spring提供了一個(gè)接口類-BeanPostProcessor,我們叫他:bean的加工器,應(yīng)該是在bean的實(shí)例化過(guò)程中對(duì)bean做一些包裝處理,里邊提供兩個(gè)方法applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization。

根據(jù)以上代碼,我們得知,在invokeInitMethods的執(zhí)行前后,spring會(huì)分別調(diào)用所有的BeanPostProcessor,執(zhí)行其中的方法,那么invokeInitMethods的具體內(nèi)容我們?nèi)孕枰聪?,發(fā)現(xiàn)此方法主要作用有兩個(gè):

判斷bean是否繼承了InitializingBean,如果繼承接口,執(zhí)行afterPropertiesSet()方法

獲得是否設(shè)置了init-method屬性,如果設(shè)置了,就執(zhí)行設(shè)置的方法

這里幾個(gè)典型的應(yīng)用場(chǎng)景如:

解析bean的注解,將注解中的字段轉(zhuǎn)化為屬性

統(tǒng)一將屬性在執(zhí)行前,注入bean中,如數(shù)據(jù)庫(kù)訪問(wèn)的sqlMap,如嚴(yán)重服務(wù),這樣不需要每個(gè)bean都配置屬性

打印日志,記錄時(shí)間等。
詳細(xì)了解BeanPostProcessor的使用可以參考這里BeanPostProcessor的使用

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {

        boolean isInitializingBean = (bean instanceof 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(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            ((InitializingBean) bean).afterPropertiesSet();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

到了這里,spring才真正地實(shí)例化并初始化bean。 所以在進(jìn)入initializeBean方法里,我們大概可以總結(jié)出bean的初始化順序:
XXAware接口的實(shí)現(xiàn)->postProcessBeforeInitialization->InitializingBean的afterPropertiesSet -> custom Init方法->postProcessAfterInitialization

如有錯(cuò)誤,歡迎指正。如果對(duì)你有幫助的話,順便點(diǎn)個(gè)贊哈!

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67555.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)代理則無(wú)此限制。 1. 背景 本文承接上文,來(lái)繼續(xù)說(shuō)說(shuō) IOC 和 AOP 的仿寫。在上文中,我實(shí)現(xiàn)了一個(gè)很簡(jiǎn)單的 IOC 和 AOP 容器。上文實(shí)現(xiàn)的 IOC 和 AOP 功能很單一,且 I...

    AlexTuan 評(píng)論0 收藏0
  • Spring IOC 容器源碼分析 - 循環(huán)依賴的解決辦法

    摘要:實(shí)例化時(shí),發(fā)現(xiàn)又依賴于。一些緩存的介紹在進(jìn)行源碼分析前,我們先來(lái)看一組緩存的定義。可是看完源碼后,我們似乎仍然不知道這些源碼是如何解決循環(huán)依賴問(wèn)題的。 1. 簡(jiǎn)介 本文,我們來(lái)看一下 Spring 是如何解決循環(huán)依賴問(wèn)題的。在本篇文章中,我會(huì)首先向大家介紹一下什么是循環(huán)依賴。然后,進(jìn)入源碼分析階段。為了更好的說(shuō)明 Spring 解決循環(huán)依賴的辦法,我將會(huì)從獲取 bean 的方法getB...

    aikin 評(píng)論0 收藏0
  • Spring IOC 容器源碼分析 - 填充屬性到 bean 原始對(duì)象

    摘要:源碼分析源碼一覽本節(jié),我們先來(lái)看一下填充屬性的方法,即。所有的屬性值是在方法中統(tǒng)一被注入到對(duì)象中的。檢測(cè)是否存在與相關(guān)的或。這樣可以在很大程度上降低源碼分析的難度。若候選項(xiàng)是非類型,則表明已經(jīng)完成了實(shí)例化,此時(shí)直接返回即可。 1. 簡(jiǎn)介 本篇文章,我們來(lái)一起了解一下 Spring 是如何將配置文件中的屬性值填充到 bean 對(duì)象中的。我在前面幾篇文章中介紹過(guò) Spring 創(chuàng)建 bea...

    SKYZACK 評(píng)論0 收藏0
  • Spring IOC 容器源碼分析 - 創(chuàng)建原始 bean 對(duì)象

    摘要:你也會(huì)了解到構(gòu)造對(duì)象的兩種策略。構(gòu)造方法參數(shù)數(shù)量低于配置的參數(shù)數(shù)量,則忽略當(dāng)前構(gòu)造方法,并重試。通過(guò)默認(rèn)構(gòu)造方法創(chuàng)建對(duì)象看完了上面冗長(zhǎng)的邏輯,本節(jié)來(lái)看點(diǎn)輕松的吧通過(guò)默認(rèn)構(gòu)造方法創(chuàng)建對(duì)象。 1. 簡(jiǎn)介 本篇文章是上一篇文章(創(chuàng)建單例 bean 的過(guò)程)的延續(xù)。在上一篇文章中,我們從戰(zhàn)略層面上領(lǐng)略了doCreateBean方法的全過(guò)程。本篇文章,我們就從戰(zhàn)術(shù)的層面上,詳細(xì)分析doCreat...

    sutaking 評(píng)論0 收藏0
  • Spring IOC 容器源碼分析 - 創(chuàng)建單例 bean 的過(guò)程

    摘要:關(guān)于創(chuàng)建實(shí)例的過(guò)程,我將會(huì)分幾篇文章進(jìn)行分析。源碼分析創(chuàng)建實(shí)例的入口在正式分析方法前,我們先來(lái)看看方法是在哪里被調(diào)用的。時(shí),表明方法不存在,此時(shí)拋出異常。該變量用于表示是否提前暴露單例,用于解決循環(huán)依賴。 1. 簡(jiǎn)介 在上一篇文章中,我比較詳細(xì)的分析了獲取 bean 的方法,也就是getBean(String)的實(shí)現(xiàn)邏輯。對(duì)于已實(shí)例化好的單例 bean,getBean(String) ...

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

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

0條評(píng)論

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