【spring源码分析】加载bean过程(1)

来源:互联网 发布:sql语句编写 编辑:程序博客网 时间:2024/06/08 15:28

上文中说明spring的加载大致过程,本文会对spring的加载过程进行细致的分析。上次说过refresh()是spring加载的核心方法,再次列一下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) {                logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);                // Destroy already created singletons to avoid dangling resources.                destroyBeans();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }        }    }

prepareRefresh()

第一个是prepareRefresh(),代码如下:

    protected void prepareRefresh() {        this.startupDate = System.currentTimeMillis();        this.active.set(true);        if (logger.isInfoEnabled()) {            logger.info("Refreshing " + this);        }        // Initialize any placeholder property sources in the context environment        initPropertySources();        // Validate that all properties marked as required are resolvable        // see ConfigurablePropertyResolver#setRequiredProperties        getEnvironment().validateRequiredProperties();    }

prepareRefresh()是对于spring刷新上下文做准备工作。

1.设置刷新的开始时间,可以用来统计耗时

2.设置context的active标识符为true

3.初始化和检测property,默认不做操作

obtainFreshBeanFactory()

obtainFreshBeanFactory()的作用是获取刷新Spring上下文的Bean工厂,其代码实现为:

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {        refreshBeanFactory();        ConfigurableListableBeanFactory beanFactory = getBeanFactory();        if (logger.isDebugEnabled()) {            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);        }        return beanFactory;    }

其核心是第二行的refreshBeanFactory方法,这是一个抽象方法,有AbstractRefreshableApplicationContext和GenericApplicationContext这两个子类实现了这个方法,看一下上文的ClassPathXmlApplicationContext的继承关系图即知,调用的应当是AbstractRefreshableApplicationContext中实现的refreshBeanFactory,其源码为:

    /**     * This implementation performs an actual refresh of this context's underlying     * bean factory, shutting down the previous bean factory (if any) and     * initializing a fresh bean factory for the next phase of the context's lifecycle.     */    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);        }    }

该方法首先销毁之前的bean工厂,然后重新创建一个bean工厂,核心代码在12行createBeanFactory()。loadBeanDefinitions(beanFactory)是记载关于bean的定义如xml配置等。

prepareBeanFactory(beanFactory)等方法

prepareBeanFactory(beanFactory)以及下postProcessBeanFactory(beanFactory)等方法是对于bean工厂和context的处理。

finishBeanFactoryInitialization(beanFactory)

重点介绍finishBeanFactoryInitialization(beanFactory) ,这里对于所有非懒加载、单例的实例化。源码如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {        // Initialize conversion service for this context.        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {            beanFactory.setConversionService(                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));        }        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);        for (String weaverAwareName : weaverAwareNames) {            getBean(weaverAwareName);        }        // Stop using the temporary ClassLoader for type matching.        beanFactory.setTempClassLoader(null);        // Allow for caching all bean definition metadata, not expecting further changes.        beanFactory.freezeConfiguration();        // Instantiate all remaining (non-lazy-init) singletons.        beanFactory.preInstantiateSingletons();    }

核心在于最后的beanFactory.preInstantiateSingletons(),代码如下:

public void preInstantiateSingletons() throws BeansException {        if (this.logger.isDebugEnabled()) {            this.logger.debug("Pre-instantiating singletons in " + this);        }        // 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);        // Trigger initialization of all non-lazy singleton beans...        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>() {                            @Override                            public Boolean run() {                                return ((SmartFactoryBean<?>) factory).isEagerInit();                            }                        }, getAccessControlContext());                    }                    else {                        isEagerInit = (factory instanceof SmartFactoryBean &&                                ((SmartFactoryBean<?>) factory).isEagerInit());                    }                    if (isEagerInit) {                        getBean(beanName);                    }                }                else {                    getBean(beanName);                }            }        }        // Trigger post-initialization callback for all applicable beans...        for (String beanName : beanNames) {            Object singletonInstance = getSingleton(beanName);            if (singletonInstance instanceof SmartInitializingSingleton) {                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;                if (System.getSecurityManager() != null) {                    AccessController.doPrivileged(new PrivilegedAction<Object>() {                        @Override                        public Object run() {                            smartSingleton.afterSingletonsInstantiated();                            return null;                        }                    }, getAccessControlContext());                }                else {                    smartSingleton.afterSingletonsInstantiated();                }            }        }    }

第1-12行先取出已加载好的bean name,并对于非RootBeanDefinition转换为RootBeanDefinition以供后续操作。

第13行在这里实例化需要满足3个条件:

1).非抽象的

2).必须是单例的

3).非懒加载的

第14-35行,先判断bean是否实现了FactoryBean,如果是的话接着判断是否是实现SmartFactoryBean以及是否isEagerInit ,如果都是的话,实例化这个bean。
Java开发人员不需要关注这段代码,因为SmartFactoryBean基本不会用到。一般类都是直接执行了34行,getBean(beanName);

跟踪getBean(beanName)方法,最终执行的是AbstractBeanFactory的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);            }            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 dependsOnBean : dependsOn) {                        if (isDependent(beanName, dependsOnBean)) {                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                    "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");                        }                        registerDependentBean(dependsOnBean, beanName);                        getBean(dependsOnBean);                    }                }                // 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 '" + 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;    }

首先第9行~第21行的代码,首先检查一下缓存是否已经加载过Bean,没有的话往下执行。

第26-51行进行一些检查,包括bean是否是prototype的、是否抽象的等

第54-64,检查是否有依赖类,如有的话优先加载。我们经常在bean标签中看到depends-on这个属性,就是通过这段保证了depends-on依赖的Bean会优先于当前Bean被加载。

第67、86、99分别有3个判断,这里是加载单例的bean,从67进行,重点是72行的createBean方法。

    @Override    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;    }

重点是32行的doCreateBean方法。

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<Object>() {                @Override                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;    }

执行到第8行createBeanInstance方法

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {        // Make sure bean class is actually resolved at this point.        Class<?> beanClass = resolveBeanClass(mbd, beanName);        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());        }        if (mbd.getFactoryMethodName() != null)  {            return instantiateUsingFactoryMethod(beanName, mbd, args);        }        // Shortcut when re-creating the same bean...        boolean resolved = false;        boolean autowireNecessary = false;        if (args == null) {            synchronized (mbd.constructorArgumentLock) {                if (mbd.resolvedConstructorOrFactoryMethod != null) {                    resolved = true;                    autowireNecessary = mbd.constructorArgumentsResolved;                }            }        }        if (resolved) {            if (autowireNecessary) {                return autowireConstructor(beanName, mbd, null, null);            }            else {                return instantiateBean(beanName, mbd);            }        }        // 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);    }

到最后的instantiateBean方法。

    public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {        // Don't override the class with CGLIB if no overrides.        if (bd.getMethodOverrides().isEmpty()) {            Constructor<?> constructorToUse;            synchronized (bd.constructorArgumentLock) {                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;                if (constructorToUse == null) {                    final Class<?> clazz = bd.getBeanClass();                    if (clazz.isInterface()) {                        throw new BeanInstantiationException(clazz, "Specified class is an interface");                    }                    try {                        if (System.getSecurityManager() != null) {                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {                                @Override                                public Constructor<?> run() throws Exception {                                    return clazz.getDeclaredConstructor((Class[]) null);                                }                            });                        }                        else {                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);                        }                        bd.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(bd, beanName, owner);        }    }

这里主要是选择bean的构造函数,到31行instantiateClass方法。

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

第5行通过反射来实例化bean。看到前面有一步makeAccessible,这意味着即使Bean的构造函数是private、protected的,依然不影响Bean的构造。

本文对于spring加载bean的流程进行了梳理,下一文将对于bean实例化部分进行着重分析。

本文参考:五月的仓颉的博客

原创粉丝点击