SpringIoc源码(十八)- BeanFactory(七)- getBean(doCreateBean - createBeanInstance实例创建)

目录

 1、Supplier方式创建对象

 2、工厂方法创建对象

 3、有参构造创建对象

 4、无参构造创建对象


    当创建Bean时,肯定是先通过反射创建该对象。只是Spring除了直接用反射实例化对象外还允许传入Supplier、或者设置factory-mtehod等方式。不论哪种方式初始化完成对象的创建后,会将该对象使用装饰器模式设置一些容器属性(丰富该对象)然后进行返回BeanWrapperImpl类型。

    1、先检查beanClass类型;

    2、如果存在Supplier类型的instanceSupplier存在,则调用其get方法初始化实例。

    3、然后判断是否存在FactoryMethodName,是则调用instantiateUsingFactoryMethod获取(过程很复杂先不分析了)

    4、如果有设置resolvedConstructorOrFactoryMethod属性则可能直接就能决定初始化的有参或者无参构造;否则就会遍历所有的SmartInstantiationAwareBeanPostProcessor,也可以指定构造器。比如只有一个有参数构造函数时则通过AutowiredAnnotationBeanPostProcessor将在这里返回构造器。如下:

@Component
public class AaaComponent {

    BbbComponent bbbComponent;
    
    public AaaComponent(BbbComponent bbbComponent) {
        this.bbbComponent = bbbComponent;
    }
}

    5、通过参数确定构造函数进行初始化调用autowireConstructor方法

    6、如果不存在工厂方法,也不存在参数构造,则调用默认无参构造函数初始化(instantiateBean方法)

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable 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());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

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

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    return instantiateBean(beanName, mbd);
}

 1、Supplier方式创建对象

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
    Object instance;
    String outerBean = this.currentlyCreatedBean.get();
    this.currentlyCreatedBean.set(beanName);
    // 省略try catch
    instance = instanceSupplier.get();
    if (instance == null) {
        instance = new NullBean();
    }
    BeanWrapper bw = new BeanWrapperImpl(instance);
    initBeanWrapper(bw);
    return bw;
}

     如果BeanDefinition发现设置了instanceSupplier属性,则调用其get方法获取到的就认为是实例对象。

但是需要将其进行包装成BeanWrapperImpl返回。所以不论使用哪种方式创建对象都会调用initBeanWrapper方法。将容器级别的ConversionService和PropertyEditor列表,都设置给所以的Bean。即这两个类型的配置即使容器级别的,也是每个Bean都拥有的。

protected void initBeanWrapper(BeanWrapper bw) {
    bw.setConversionService(getConversionService());
    registerCustomEditors(bw);
}

 2、工厂方法创建对象

    如果在<bean />标签中设置了factory-bean属性,或者在BeanDefinition中设置了factoryMethodName属性。那么可以直接从该指定方法中获取对象。

protected BeanWrapper instantiateUsingFactoryMethod(
    String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this)
        .instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}

    instantiateUsingFactoryMethod方法太长,过程大致如下:

1、处理initBeanWrapper(如上)

2、根据factoryBeanName名称字符串,调用getBean(factoryBeanName)返回对象

3、根据对象的可用的方法,已经传入的参数等,排除其他最终决定调用方法和参数

4、调用下面的策略(CglibSubclassingInstantiationStrategy)方法实例化对象

beanFactory.getInstantiationStrategy().instantiate(
      mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args)

核心代码为:

Object result = factoryMethod.invoke(factoryBean, args)

 3、有参构造创建对象

protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, 
    @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this)
        .autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

     创建过程大致与上面的相同,最终都会调用CglibSubclassingInstantiationStrategy的instantiate方法。

 4、无参构造创建对象

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    Object beanInstance;
    // 省略try catch代码
    final BeanFactory parent = this;
    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
    BeanWrapper bw = new BeanWrapperImpl(beanInstance);
    initBeanWrapper(bw);
    return bw;
}

    无参构造的过程,上面的方法都会经历。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值