温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring的单例Bean初始化过程是什么

发布时间:2022-03-19 10:23:18 来源:亿速云 阅读:161 作者: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