美文网首页
spring源码解析 -- 构造bean

spring源码解析 -- 构造bean

作者: binecy | 来源:发表于2019-03-18 10:48 被阅读0次

    Spring源码解析 -- 读取bean元数据
    spring源码解析 -- 构造bean
    spring源码解析 -- 注入属性
    spring源码解析 -- Spring Context
    Spring源码解析 -- AOP原理(1)
    Spring源码解析 -- AOP原理(2)
    Spring源码解析 -- SpringMvc原理

    源码分析基于spring 4.3.x

    前面文章已经分析了spring如何加载xml配置中的bean元数据,现在来分析一下spring构造bean的过程。
    关于阅读源码的思路,可参考 -- 如何阅读java源码

    BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("application.xml"));
    Blog bean = (Blog)xmlBeanFactory.getBean("blog");
    

    XmlBeanFactory的父类AbstractBeanFactory是spring中一个很重要的类,他为BeanFactory提供基础服务。构造bean就是由该类实现的。
    AbstractBeanFactory#doGetBean

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
        final String beanName = transformedBeanName(name);
        Object bean;
    
        Object sharedInstance = getSingleton(beanName); // #1
        if (sharedInstance != null && args == null) {
            ...
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  // #2
        }
    
        else {
            if (isPrototypeCurrentlyInCreation(beanName)) { // #3
                throw new BeanCurrentlyInCreationException(beanName);
            }
    
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {   // #4
                ...
            }
    
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);    // #5
            }
    
            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  // #6
                checkMergedBeanDefinition(mbd, beanName, args);
    
                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);   
                        try {
                            getBean(dep);   // #7
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
    
                // Create bean instance.
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {     // #8
                        try {
                            return createBean(beanName, mbd, args); // #9
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
    
                ... 
            }
            catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
    
        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isInstance(bean)) {   // #10
            try {
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
    
    

    #1 单例的bean,先从缓冲中查询
    getSingleton方法会查询
    singletonObject,earlySingletonObjects,singletonFactories等缓存,它们都是简单的map,缓存了单例的bean,正在创建的bean和ObjectFactory对象。

    #2 如果构造的bean是FactoryBean,进行对应的处理
    getObjectForBeanInstance方法会根据参数beanInstance进行处理,如果beanInstance是FactoryBean,会调用其getObject()方法创建bean,如果不是,返回直接返回该beanInstance参数。
    FactoryBean是spring提供的一个扩展接口,用户实现该接口可以自定义bean的创建。

    #3 如果现在正在创建这个bean,则直接报错,这时很可能陷入循环引用了
    #4 当前BeanFactory不存在对应的BeanDefinition,尝试通过父BeanFactory构造bean
    #5 标记这个bean正在构造中
    #6 获取BeanDefinition
    前面解析spring加载bean数据的文章中说过,spring会将bean元数据转化为BeanDefinition,存入DefaultListableBeanFactory#beanDefinitionMap属性中。
    getMergedLocalBeanDefinition方法会获取对应BeanDefinition,如果BeanDefinition存在ParentName,会获取父BeanDefinition,再合并元数据。

    #7 先构造依赖的bean
    #8 使用ObjectFactory构造并注册一个bean,getSingleton方法也要完成构造bean的准备和善后工作。
    #9 匿名的ObjectFactory,调用AbstractAutowireCapableBeanFactory#createBean进行实际的构造bean工作
    #10 bean类型转换

    spring中bean有singleton,prototype等范围,这里只关注singleton类型的bean的构造过程。

    #8步骤,DefaultSingletonBeanRegistry#getSingleton(注意getSingleton有重载方法)

        public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "Bean name must not be null");
            synchronized (this.singletonObjects) {
                Object singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    ...
                    beforeSingletonCreation(beanName);  // #1
                    boolean newSingleton = false;
                    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                    if (recordSuppressedExceptions) {
                        this.suppressedExceptions = new LinkedHashSet<>();
                    }
                    try {
                        singletonObject = singletonFactory.getObject(); // #2
                        newSingleton = true;
                    }
                    ...
                    finally {
                        if (recordSuppressedExceptions) {
                            this.suppressedExceptions = null;
                        }
                        afterSingletonCreation(beanName);
                    }
                    if (newSingleton) {
                        addSingleton(beanName, singletonObject);    // #3
                    }
                }
                return singletonObject;
            }
        }
    

    #1 仅做错误检查,也是提供给子类的扩展方法
    #2 真正构造bean的方法,调用AbstractBeanFactory#doGetBean方法#9步骤的匿名类处理,实际调用AbstractAutowireCapableBeanFactory#createBean
    #3 单例的bean,加入缓冲中

    真正的构造bean方法
    AbstractAutowireCapableBeanFactory#createBean

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;
    
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);   // #1
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        try {
            mbdToUse.prepareMethodOverrides();  // #2
        }
        ...
    
        try {
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);   // #3
            if (bean != null) {
                return bean;
            }
        }
        ...
    
        try {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);   // #4
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        ...
    }
    

    #1 确保jdk已加载bean的class
    #2 对bean的lookup-method和replace-method做检查工作
    #3 spring的扩展机制,调用BeanPostProcessor#postProcessBeforeInstantiation方法,
    注意,如果resolveBeforeInstantiation返回非null对象,这里将直接返回该对象作为bean,spring不再构造该bean。
    #4 继续构造bean

    AbstractAutowireCapableBeanFactory#doCreateBean

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
    
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   // #1
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);  // #2
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
    
        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);   // #3
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
    
        ...
    
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);   // #4
            exposedObject = initializeBean(beanName, exposedObject, mbd);   // #5
        }
        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);
            }
        }
    
        ...
    
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);     // #6
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
    
        return exposedObject;
    }
    

    #1 查询BeanWrapper缓冲
    #2 构造一个空的(属性未注入)bean,生成BeanWrapper
    #3 spring扩展机制,调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
    #4 populateBean负责注入属性到bean中,后面有对应文章解析该步骤
    #5 spring扩展机制,调用Aware方法和init方法,并调用BeanPostProcessor#postProcessAfterInitialization方法。
    #6 如果bean存在Destroy方法,或存在对应的DestructionAwareBeanPostProcessor,注册该bean为disposable。(该bean销毁时要调用对应的销毁机制)

    这里涉及到循环引用的处理,比较繁琐,所以省略了很多代码,只保留bean创建相关的代码。

    BeanWrapper是对bean的包装类,提供了对bean的class,property进行操作的方法。

    #2步骤,AbstractAutowireCapableBeanFactory#createBeanInstance

        protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
            Class<?> beanClass = resolveBeanClass(mbd, beanName);   // #1
    
            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)  {  // #2
                return instantiateUsingFactoryMethod(beanName, mbd, args);
            }
    
            boolean resolved = false;
            boolean autowireNecessary = false;
            if (args == null) {
                synchronized (mbd.constructorArgumentLock) {
                    if (mbd.resolvedConstructorOrFactoryMethod != null) {   // #3
                        resolved = true;
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }
            if (resolved) { 
                if (autowireNecessary) {
                    return autowireConstructor(beanName, mbd, null, null);  // #4
                }
                else {
                    return instantiateBean(beanName, mbd);  // #5
                }
            }
    
            Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);  // #6
            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);
        }
    
    
    

    #1 获取bean的class
    #2 如果存在factoryMethod,通过factoryMethod构造bean
    #3 判断该class已经构造过bean了
    #4 使用之前选择好的构造函数构造bean
    #5 使用无参构造函数构造bean
    #6 spring根据构造函数的参数,自行选择构造函数,逻辑较复杂。

    下面看看使用无参构造方法构造bean,AbstractAutowireCapableBeanFactory#instantiateBean -> SimpleInstantiationStrategy#instantiate

    public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
            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) {
                                ...
                            }
                            else {
                                constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);   // #1
                            }
                            bd.resolvedConstructorOrFactoryMethod = constructorToUse;   // #2
                        }
                        catch (Throwable ex) {
                            throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                        }
                    }
                }
                return BeanUtils.instantiateClass(constructorToUse);    // #3
            }
            else {
                return instantiateWithMethodInjection(bd, beanName, owner);     // #4
            }
        }
    

    #1 获取无参构造函数
    #2 添加无参构造函数加入到BeanDefinition缓存中
    #2 BeanUtils#instantiateClass通过构造函数构造bean
    #3 bean中存在lookup-method或replace-method,必须使用CGLIB构造bean

    到这里,bean已经构造完成,下一步就是注入属性了。

    如果您觉得本文不错,欢迎关注我的微信公众号,您的关注是我坚持的动力!


    相关文章

      网友评论

          本文标题:spring源码解析 -- 构造bean

          本文链接:https://www.haomeiwen.com/subject/pnrbyqtx.html