spring源码bean的加载过程

本文详细介绍了Spring框架中Bean的加载过程,包括如何通过AbstractBeanFactory获取Bean实例、依赖注入及生命周期管理等关键步骤,并解释了单例和原型Bean的区别。

Bean的加载

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory

 

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {

        return doGetBean(name, requiredType, args, false);

    }

@SuppressWarnings("unchecked")

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

            }

 

            try {

                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 dep : dependsOn) {

                        if (isDependent(beanName, dep)) {

                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,

                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");

                        }

                        registerDependentBean(dep, beanName);

                        getBean(dep);

                    }

                }

 

                // Create bean instance.

                if (mbd.isSingleton()) {

                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {

                        @Override

                        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 name '" + scopeName + "'");

                    }

                    try {

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

                            @Override

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

                    }

                }

            }

            catch (BeansException ex) {

                cleanupAfterBeanCreationFailure(beanName);

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

    }

bean加载过程

 

225322_acO6_1866807.png

转载于:https://my.oschina.net/iioschina/blog/831360

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值