亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

Spring這么初始化Bean實例對象

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

這篇文章主要介紹了Spring這么初始化Bean實例對象的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Spring這么初始化Bean實例對象文章都會有所收獲,下面我們一起來看看吧。

代碼入口

DefaultListableBeanFactory的preInstantiateSingletons方法

DefaultListableBeanFactory的preInstantiateSingletons方法,顧名思義,初始化所有的單例Bean,看一下方法的定義:

public void preInstantiateSingletons() throws BeansException {

    if (this.logger.isInfoEnabled()) {

        this.logger.info("Pre-instantiating singletons in " + this);

    }

    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.

        List<String> beanNames = new ArrayList<String>(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<Boolean>() {

                            public Boolean run() {

                                return ((SmartFactoryBean) factory).isEagerInit();

                            }

                        }, getAccessControlContext());

                    }

                    else {

                        isEagerInit = (factory instanceof SmartFactoryBean &&

                                ((SmartFactoryBean) factory).isEagerInit());

                    }

                    if (isEagerInit) {

                        getBean(beanName);

                    }

                }

                else {

                    getBean(beanName);

                }

            }

        }

    }

}

前面的代碼比較簡單,根據beanName拿到BeanDefinition(即Bean的定義)。由于此方法實例化的是所有非懶加載的單例Bean,因此要實例化Bean,必須滿足11行的三個定義:

(1)不是抽象的

(2)必須是單例的

(3)必須是非懶加載的

接著簡單看一下第12行~第29行的代碼,這段代碼主要做的是一件事情:首先判斷一下Bean是否FactoryBean的實現,接著判斷Bean是否SmartFactoryBean的實現,假如Bean是SmartFactoryBean的實現并且eagerInit(這個單詞字面意思是渴望加載,找不到一個好的詞語去翻譯,意思就是定義了這個Bean需要立即加載的意思)的話,會立即實例化這個Bean。Java開發人員不需要關注這段代碼,因為SmartFactoryBean基本不會用到,我翻譯一下Spring官網對于SmartFactoryBean的定義描述:

  • FactoryBean接口的擴展接口。接口實現并不表示是否總是返回單獨的實例對象,比如FactoryBean.isSingleton()實現返回false的情況并不清晰地表示每次返回的都是單獨的實例對象

     

  • 不實現這個擴展接口的簡單FactoryBean的實現,FactoryBean.isSingleton()實現返回false總是簡單地告訴我們每次返回的都是單獨的實例對象,暴露出來的對象只能夠通過命令訪問

     

  • 注意:這個接口是一個有特殊用途的接口,主要用于框架內部使用與Spring相關。通常,應用提供的FactoryBean接口實現應當只需要實現簡單的FactoryBean接口即可,新方法應當加入到擴展接口中去

代碼示例

為了后面的代碼分析方便,事先我定義一個Bean:

package org.xrq.action;

 

import org.springframework.beans.factory.BeanClassLoaderAware;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.beans.factory.InitializingBean;

 

public class MultiFunctionBean implements InitializingBean, BeanNameAware, BeanClassLoaderAware {

 

    private int    propertyA;

 

    private int    propertyB;

 

    public int getPropertyA() {

        return propertyA;

    }

 

    public void setPropertyA(int propertyA) {

        this.propertyA = propertyA;

    }

 

    public int getPropertyB() {

        return propertyB;

    }

 

    public void setPropertyB(int propertyB) {

        this.propertyB = propertyB;

    }

 

    public void initMethod() {

        System.out.println("Enter MultiFunctionBean.initMethod()");

    }

 

    @Override

    public void setBeanClassLoader(ClassLoader classLoader) {

        System.out.println("Enter MultiFunctionBean.setBeanClassLoader(ClassLoader classLoader)");

    }

 

    @Override

    public void setBeanName(String name) {

        System.out.println("Enter MultiFunctionBean.setBeanName(String name)");

    }

 

    @Override

    public void afterPropertiesSet() throws Exception {

        System.out.println("Enter MultiFunctionBean.afterPropertiesSet()");

    }

 

    @Override

    public String toString() {

        return "MultiFunctionBean [propertyA=" + propertyA + ", propertyB=" + propertyB + "]";

    }

 

}

定義對應的spring.xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

 

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 

    <bean id="multiFunctionBean" class="org.xrq.action.MultiFunctionBean" init-method="initMethod" />

 

</beans>

利用這個MultiFunctionBean,我們可以用來探究Spring加載Bean的多種機制。

doGetBean方法構造Bean流程

上面把getBean之外的代碼都分析了一下,看代碼就可以知道,獲取Bean對象實例,都是通過getBean方法,getBean方法最終調用的是DefaultListableBeanFactory的父類AbstractBeanFactory類的doGetBean方法,因此這部分重點分析一下doGetBean方法是如何構造出一個單例的Bean的。

看一下doGetBean方法的代碼實現,比較長:

protected <T> T doGetBean(

        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)

        throws BeansException {

 

    final String beanName = transformedBeanName(name);

    Object bean;

 

    // Eagerly check singleton cache for manually registered singletons.

    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 {

        // Fail if we're already creating this bean instance:

        // We're assumably within a circular reference.

        if (isPrototypeCurrentlyInCreation(beanName)) {

            throw new BeanCurrentlyInCreationException(beanName);

        }

 

        // Check if bean definition exists in this factory.

        BeanFactory parentBeanFactory = getParentBeanFactory();

        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

            // Not found -> check parent.

            String nameToLookup = originalBeanName(name);

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

        }

 

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

        }

 

        else if (mbd.isPrototype()) {

            // It's a prototype -> create a new instance.

            Object prototypeInstance = null;

            try {

                beforePrototypeCreation(beanName);

                prototypeInstance = createBean(beanName, mbd, args);

            }

            finally {

                afterPrototypeCreation(beanName);

            }

            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);

        }

 

        else {

            String scopeName = mbd.getScope();

            final Scope scope = this.scopes.get(scopeName);

            if (scope == null) {

                throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");

            }

            try {

                Object scopedInstance = scope.get(beanName, new ObjectFactory() {

                    public Object getObject() throws BeansException {

                            beforePrototypeCreation(beanName);

                        try {

                            return createBean(beanName, mbd, args);

                        }

                        finally {

                            afterPrototypeCreation(beanName);

                        }

                    }

                });

                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);

            }

            catch (IllegalStateException ex) {

                throw new BeanCreationException(beanName,

                        "Scope '" + scopeName + "' is not active for the current thread; " +

                        "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",

                        ex);

            }

        }

    }

 

    // Check if required type matches the type of the actual bean instance.

    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {

        try {

            return getTypeConverter().convertIfNecessary(bean, requiredType);

        }

        catch (TypeMismatchException ex) {

            if (logger.isDebugEnabled()) {

                logger.debug("Failed to convert bean '" + name + "' to required type [" +

                        ClassUtils.getQualifiedName(requiredType) + "]", ex);

            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

        }

    }

    return (T) bean;

}

關于“Spring這么初始化Bean實例對象”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Spring這么初始化Bean實例對象”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

玛曲县| 石河子市| 肥城市| 河西区| 丽江市| 辉南县| 四会市| 虎林市| 红安县| 图木舒克市| 安徽省| 安国市| 太仆寺旗| 垣曲县| 留坝县| 阿图什市| 惠东县| 建德市| 澎湖县| 太仓市| 平乡县| 深圳市| 高雄市| 昌图县| 马龙县| 绥化市| 安丘市| 金湖县| 来凤县| 九龙县| 阿鲁科尔沁旗| 金川县| SHOW| 澳门| 黄石市| 根河市| 那曲县| 读书| 大理市| 澳门| 高雄县|