91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring的單例Bean初始化過程是什么

發布時間:2022-03-19 10:23:18 來源:億速云 閱讀:159 作者:iii 欄目:云計算

本篇內容介紹了“Spring的單例Bean初始化過程是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

createBean方法是AbstractBeanFactory的子類AbstractAutowireCapableBeanFactory的一個方法,看一下它的方法實現:

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;

}

前面的代碼都沒什么意義,代碼執行到第31行:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

    // Instantiate the 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.

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

        }

    }

 

    if (earlySingletonExposure) {

        Object earlySingletonReference = getSingleton(beanName, false);

        if (earlySingletonReference != null) {

            if (exposedObject == bean) {

                exposedObject = earlySingletonReference;

            }

            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {

                String[] dependentBeans = getDependentBeans(beanName);

                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);

                for (String dependentBean : dependentBeans) {

                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {

                        actualDependentBeans.add(dependentBean);

                    }

                }

                if (!actualDependentBeans.isEmpty()) {

                    throw new BeanCurrentlyInCreationException(beanName,

                            "Bean with name '" + beanName + "' has been injected into other beans [" +

                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +

                            "] in its raw version as part of a circular reference, but has eventually been " +

                            "wrapped. This means that said other beans do not use the final version of the " +

                            "bean. This is often the result of over-eager type matching - consider using " +

                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");

                }

            }

        }

    }

 

    // Register bean as disposable.

    try {

        registerDisposableBeanIfNecessary(beanName, bean, mbd);

    }

    catch (BeanDefinitionValidationException ex) {

        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);

    }

 

    return exposedObject;

}

代碼跟蹤到這里,已經到了主流程,接下來分段分析doCreateBean方法的代碼。

創建Bean實例

第8行的createBeanInstance方法,會創建出Bean的實例,并包裝為BeanWrapper,看一下createBeanInstance方法,只貼最后一段比較關鍵的:

// Need to determine the constructor...

Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

if (ctors != null ||

        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {

    return autowireConstructor(beanName, mbd, ctors, args);

}

 

// No special handling: simply use no-arg constructor.

return instantiateBean(beanName, mbd);

意思是bean標簽使用構造函數注入屬性的話,執行第6行,否則執行第10行。MultiFunctionBean使用默認構造函數,使用setter注入屬性,因此執行第10行代碼:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

    try {

        Object beanInstance;

        final BeanFactory parent = this;

        if (System.getSecurityManager() != null) {

            beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {

                public Object run() {

                    return getInstantiationStrategy().instantiate(mbd, beanName, parent);

                }

            }, getAccessControlContext());

        }

        else {

            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

        }

        BeanWrapper bw = new BeanWrapperImpl(beanInstance);

        initBeanWrapper(bw);

        return bw;

    }

    catch (Throwable ex) {

        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

    }

}

代碼執行到13行:

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

    // Don't override the class with CGLIB if no overrides.

    if (beanDefinition.getMethodOverrides().isEmpty()) {

        Constructor<?> constructorToUse;

        synchronized (beanDefinition.constructorArgumentLock) {

            constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;

            if (constructorToUse == null) {

                final Class clazz = beanDefinition.getBeanClass();

                if (clazz.isInterface()) {

                    throw new BeanInstantiationException(clazz, "Specified class is an interface");

                }

                try {

                    if (System.getSecurityManager() != null) {

                        constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {

                            public Constructor run() throws Exception {

                                return clazz.getDeclaredConstructor((Class[]) null);

                            }

                        });

                    }

                    else {

                        constructorToUse = clazz.getDeclaredConstructor((Class[]) null);

                    }

                    beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;

                }

                catch (Exception ex) {

                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);

                }

            }

        }

        return BeanUtils.instantiateClass(constructorToUse);

    }

    else {

        // Must generate CGLIB subclass.

        return instantiateWithMethodInjection(beanDefinition, beanName, owner);

    }

}

整段代碼都在做一件事情,就是選擇一個使用的構造函數。當然第9行順帶做了一個判斷:實例化一個接口將報錯。

最后調用到30行,看一下代碼:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {

    Assert.notNull(ctor, "Constructor must not be null");

    try {

        ReflectionUtils.makeAccessible(ctor);

        return ctor.newInstance(args);

    }

    catch (InstantiationException ex) {

        throw new BeanInstantiationException(ctor.getDeclaringClass(),

                "Is it an abstract class?", ex);

    }

    catch (IllegalAccessException ex) {

        throw new BeanInstantiationException(ctor.getDeclaringClass(),

                "Is the constructor accessible?", ex);

    }

    catch (IllegalArgumentException ex) {

        throw new BeanInstantiationException(ctor.getDeclaringClass(),

                "Illegal arguments for constructor", ex);

    }

    catch (InvocationTargetException ex) {

        throw new BeanInstantiationException(ctor.getDeclaringClass(),

                "Constructor threw exception", ex.getTargetException());

    }

}

通過反射生成Bean的實例。看到前面有一步makeAccessible,這意味著即使Bean的構造函數是private、protected的,依然不影響Bean的構造。

最后注意一下,這里被實例化出來的Bean并不會直接返回,而是會被包裝為BeanWrapper繼續在后面使用。

“Spring的單例Bean初始化過程是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

河间市| 兴山县| 祥云县| 莱芜市| 松滋市| 英山县| 汨罗市| 田阳县| 株洲县| 宜昌市| 彩票| 太白县| 武定县| 汕头市| 乌拉特后旗| 永川市| 陈巴尔虎旗| 棋牌| 林甸县| 若羌县| 尤溪县| 桑日县| 彭水| 铁岭市| 上高县| 临桂县| 崇信县| 河津市| 赣榆县| 徐汇区| 铁力市| 赤城县| 绥江县| 遵义县| 福安市| 诏安县| 鄯善县| 沁阳市| 台东市| 保康县| 南华县|