AbstractAutowireCapableBeanFacto

2022-12-07  本文已影响0人  王侦

1.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;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        //判断当前mbd中的class是否已经加载到jvm,如果未加载,则使用类加载器将classStr加载到Jvm中,并且返回Class对象
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        //条件一:拿到mbd实例化对象时的真实Class对象。
        //条件二(!mbd.hasBeanClass()):条件成立,说明mbd在resolveBeanClass之前,是没有Class对象的。
        //条件三:成立,说明mbd有ClassName
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            // 对XML标签中定义的lookUp属性进行预处理,如果只能根据名字找到一个就标记为非重载的,这样在后续就不需要去推断到底是哪个方法了,
            // 对于@LookUp注解标注的方法是不需要在这里处理的,AutowiredAnnotationBeanPostProcessor会处理这个注解
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //可以通过后处理器,在这一步返回一个代理实例对象..注意,这里的代理对象不是Spring AOP 逻辑实现的地方。
            //instantiation 实例化不要和init 搞混。
            //后处理器调用点:创建实例之前的一个调用点。
            // 它的另外一个作用就是对AOP提供了支持,在这里会将一些不需要被代理的Bean进行标记
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            //条件成立会形成一个短路操作,这里直接返回了.
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            //核心方法:创建bean实例对象,并且生命周期的动作大部分都在这里
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

2.短路操作resolveBeforeInstantiation()

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

这里跟FactoryBean#getObject()会调用BeanPostProcessor#postProcessAfterInitialization()一样,也会调用这个方法,因为这里创建的bean也没有经过完整的生命周期,但是也会调用后置处理器初始化后的方法。

使用示例:

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    /**
     * InstantiationAwareBeanPostProcessor中自定义的方法
     * 在方法实例化之前执行  Bean对象还没有
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("--->postProcessBeforeInstantiation");

        // 利用cglib动态代理生成对象返回
        if (beanClass == Student.class) {
            Enhancer e = new Enhancer();
            e.setSuperclass(beanClass);
            e.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                    System.out.println("目标方法执行前:" + method);
                    Object object = methodProxy.invokeSuper(obj, objects);
                    System.out.println("目标方法执行后:" + method + "\n");
                    return object;
                }
            });
            Student student = (Student) e.create();
            // 返回代理类
            return student;
        }

        return null;
    }
}

配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean class="com.wz.spring.instantiation.Student" id="student" init-method="start">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" value="小刘"></constructor-arg>
    </bean>

    <!-- 注册InstantiationAwareBeanPostProcessor对象 -->
    <bean class="com.wz.spring.instantiation.MyInstantiationAwareBeanPostProcessor"></bean>

</beans>

结果:

目标方法执行前:public void com.wz.spring.instantiation.Student.study()
因为学习让我们相遇...
目标方法执行后:public void com.wz.spring.instantiation.Student.study()

3.AbstractAutowireCapableBeanFactory#doCreateBean主流程

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        //包装对象,内部最核心的字段就是咱们的真实实例。它提供了一些额外的接口方法,比如 属性访问器
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            //该方法创建出来真实的bean实例,并且将其包装到BeanWrapper实例中。
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        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 {
                    //后处理器调用点:合并bd信息,因为接下来就是populate处理依赖了..
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                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.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            //处理当前实例的依赖数据...依赖注入在这一步完成的。
            populateBean(beanName, mbd, instanceWrapper);
            //生命周期中的初始化方法的调用。
            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);
            //条件成立:说明当前bean实例 从 2级缓存获取到了...
            //说明产生循环依赖了...3级缓存 当前对象的ObjectFactory.getObject() 被调用过
            if (earlySingletonReference != null) {
                //条件成立有几种情况?
                //1.当前“真实实例”不需要被代理
                //2.当前“实例”已经被代理过了...是在ObjectFactory.getObject() 方法调用时 实现的增强代理。
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    //获取依赖当前bean的 其它beanName
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    //为什么有问题?
                    //因为咱们当前对象的AOP操作是在 当前方法的 initializeBean 这个方法完成的。
                    //在这之前 外部其它bean持有到的当前的 “bean实例” 都是尚未增强的。
                    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 " +
                                "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        try {
            //判断当前bean实例是否需要注册 析构回调。当容器销毁时,会给当前bean的析构方法进行回调。
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }

3.1 this.factoryBeanInstanceCache.remove(beanName)关于FactoryBean

// 这里申明了一个FactoryBean,并且通过@DependsOn注解申明了这个FactoryBean的创建要在orderService之后,主要目的是为了在DmzFactoryBean创建前让容器发生一次属性注入
@Component
@DependsOn("orderService")
public class DmzFactoryBean implements FactoryBean<DmzService> {
 @Override
 public DmzService getObject() throws Exception {
  return new DmzService();
 }

 @Override
 public Class<?> getObjectType() {
  return DmzService.class;
 }
}

// 没有通过注解的方式将它放到容器中,而是通过上面的DmzFactoryBean来管理对应的Bean
public class DmzService {
}

// OrderService中需要注入dmzService
@Component
public class OrderService {
 @Autowired
 DmzService dmzService;
}

DmzFactoryBean是依赖于orderService的,所以必定会先创建orderService再创建DmzFactoryBean。
orderService属性注入阶段:


为orderService进行属性注入可以分为这么几步

在创建对象时,因为此时factoryBeanInstanceCache已经缓存了这个Bean对应的对象,所以直接通过this.factoryBeanInstanceCache.remove(beanName)这行代码就返回了,避免了二次创建对象。

3.2 扩展点applyMergedBeanDefinitionPostProcessors()

        // Allow post-processors to modify the merged bean definition.
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    //后处理器调用点:合并bd信息,因为接下来就是populate处理依赖了..
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }
    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition
            //做了一件事:提取出来当前beanType类型整个继承体系内的 @Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个
            //对象,存放到 AutowiredAnnotationBeanPostProcessor 它的缓存中了,key是 beanName。
            if (bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }
    }

重点看看AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition:

AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition做了一件事:提取出来当前beanType类型整个继承体系内的 @Autowired @Value @Inject 信息 并且包装成一个InjectionMetadata的一个对象,存放到 AutowiredAnnotationBeanPostProcessor 它的缓存中了,key是 beanName。

    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        metadata.checkConfigMembers(beanDefinition);
    }
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // Quick check on the concurrent map first, with minimal locking.
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {
            synchronized (this.injectionMetadataCache) {
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {
                    if (metadata != null) {
                        metadata.clear(pvs);
                    }
                    // 获取当前clazz关注的@Autowired @Value @Inject注解信息
                    metadata = buildAutowiringMetadata(clazz);
                    this.injectionMetadataCache.put(cacheKey, metadata);
                }
            }
        }
        return metadata;
    }

3.3 依赖注入populateBean()

详情请参考:https://www.jianshu.com/p/bbf51b8553d9?v=1670512502259

3.4 初始化initializeBean()

    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //后处理器调用点:BeforeInitialization   初始化之前的后处理器调用点
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //后处理器调用点:AfterInitialization 初始化之后的后处理器的调用点
            //典型应用:Spring AOP的实现
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {

        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                //完成afterPropertiesSet接口方法调用
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            //通过接口实现了的话,就不会再调用使用init-method定义的方法了
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

3.5 注册销毁方法registerDisposableBeanIfNecessary()

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    //条件一:原型不会注册 销毁回调方法。
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
            //给当前单实例注册回调适配器。 适配器内
            // 根据当前bean实例是继承接口 还是 通过自定义
            // 来决定具体调用哪个方法 完成销毁操作。
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        else {
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}
    public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
            List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {

        Assert.notNull(bean, "Disposable bean must not be null");
        this.bean = bean;
        this.beanName = beanName;
        this.invokeDisposableBean =
                (this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
        this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
        this.acc = acc;
        String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
        if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
                !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
            this.destroyMethodName = destroyMethodName;
            Method destroyMethod = determineDestroyMethod(destroyMethodName);
            if (destroyMethod == null) {
                if (beanDefinition.isEnforceDestroyMethod()) {
                    throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
                            destroyMethodName + "' on bean with name '" + beanName + "'");
                }
            }
            else {
                Class<?>[] paramTypes = destroyMethod.getParameterTypes();
                if (paramTypes.length > 1) {
                    throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
                            beanName + "' has more than one parameter - not supported as destroy method");
                }
                else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
                    throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
                            beanName + "' has a non-boolean parameter - not supported as destroy method");
                }
                destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
            }
            this.destroyMethod = destroyMethod;
        }
        this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
    }

4.创建实例createBeanInstance()

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        //返回mbd中真实bean的Class对象。
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        //三个条件想表达的意思:bd中如果nonPublicAccessAllowed字段值为true,表示class是非公开类型的 也可以创建实例,反之false,说明是无法创建的..
        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());
        }

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

        //bean标签中配置了 factory-method的情况处理
        // bd中提供了factoryMethodName属性,那么要使用工厂方法的方式来创建对象,
        // 工厂方法又会区分静态工厂方法跟实例工厂方法
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        //表示bd对应的构造信息是否已经解析成可以反射调用的构造方法method信息了
        // 是否推断过构造方法
        boolean resolved = false;
        //是否自动匹配构造方法,构造方法是否需要注入(参数)
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                //条件成立:说明bd的构造信息已经转化成可以反射调用的method了
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    //当resolvedConstructorOrFactoryMethod 有值时,且构造方法有参数,那么可以认为这个字段值就是true。
                    //只有什么情况下这个字段是false呢?
                    //1.resolvedConstructorOrFactoryMethod == null
                    //2.当resolvedConstructorOrFactoryMethod 表示的是默认的构造方法,无参构造方法。
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            // 构造函数已经解析过了,并且这个构造函数在调用时需要自动注入参数
            if (autowireNecessary) {
                //有参数,那么就需要根据参数 去匹配合适的构造方法了...
                //拿出当前Class的所有构造器,然后根据参数信息 去匹配出一个最优的选项,然后执行最优的 构造器 创建出实例。
                // 此时部分解析好的参数已经存在了beanDefinition中,并且构造函数也在bd中
                // 那么在这里只会从缓存中去取构造函数以及参数然后反射调用
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //无参构造方法处理
                return instantiateBean(beanName, mbd);
            }
        }

        // Candidate constructors for autowiring?
        //  典型的应用:@Autowired 注解打在了 构造器方法上。参考@Autowired AutowiredAnnotationBeanPostProcessor
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        //条件一:ctors不为null:说明存在1个或多个@Autowired标注的方法。
        // 再进一步选择一个差异值最小的,参数最长的构造函数
        //条件二:mbd autowiredMode 一般情况是no
        // 没有@Autowired标注的方法,但是需要进行自动注入,
        // 那么通过autowireConstructor会去遍历类中申明的所有构造函数,
        // 并查找一个差异值最小的,参数最长的构造函数
        //条件三:条件成立,说明bean信息中配置了 构造参数信息。
        // 说明不是自动注入,配置文件中配置了构造函数要使用的参数
        //条件四:getBean时,args有参数
        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);
    }

4.1 通过factory-method创建bean

详情参见: https://www.jianshu.com/p/c9ab0026be34?v=1670424944028

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

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

ConstructorResolver用来解析构造函数跟工厂方法的代理者,并且它是通过参数匹配的方式来进行推断构造方法或者工厂方法。

三个参数:

4.2 通过构造方法创建bean

详情参见: https://www.jianshu.com/p/1b487205dbb6?v=1670428900594

5.factory-method跟构造函数的比较

通过构造函数实例化对象,多了一层处理,就是要处理构造函数上的@Autowired注解以及方法上的@LookUp注解(要决定选取哪一种实例化策略,SimpleInstantiationStrategy/CglibSubclassingInstantiationStrategy)。

在最终的选取也存在差异,对于facotyMehod而言,在宽松模式下(除ConfigurationClassBeanDefinition外,也就是扫描@Bean得到的BeanDefinition,都是宽松模式),会选取一个最精准的方法,在严格模式下,会选取一个参数最长的方法。

对于构造函数而言,会必定会选取一个参数最长的方法。



6.计算类型差异

集中情况说明:

                //typeDiffWeight 数值越高说明构造器与参数匹配度越低...
                //计算出当前构造器参数类型 与 当前 构造器参数 匹配度。
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                        argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // Choose this constructor if it represents the closest match.
                //条件成立:说明当前循环处理的 构造器 比上一次筛选出来的构造器 更优先。
                if (typeDiffWeight < minTypeDiffWeight) {
                    constructorToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousConstructors = null;
                }

判断bd是严格模式还是宽松模式,bd默认就是宽松模式,只有在ConfigurationClassBeanDefinition中使用严格模式,也就是扫描@Bean标注的方法注册的bd(对应的代码可以参考:ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod方法)

宽松模式:

public int getTypeDifferenceWeight(Class<?>[] paramTypes) {
    // 计算实际使用的参数跟方法声明的参数的差异值
   int typeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.arguments);
    // 计算没有经过类型转换的参数跟方法声明的参数的差异值
   int rawTypeDiffWeight = MethodInvoker.getTypeDifferenceWeight(paramTypes, this.rawArguments) - 1024;
   return (rawTypeDiffWeight < typeDiffWeight ? rawTypeDiffWeight : typeDiffWeight);
  }

public static int getTypeDifferenceWeight(Class<?>[] paramTypes, Object[] args) {
    int result = 0;
    for (int i = 0; i < paramTypes.length; i++) {
        // 在出现类型转换时,下面这个判断才会成立,也就是在比较rawArguments跟paramTypes的差异时才可能满足这个条件
        if (!ClassUtils.isAssignableValue(paramTypes[i], args[i])) {
            return Integer.MAX_VALUE;
        }
        if (args[i] != null) {
            Class<?> paramType = paramTypes[i];
            Class<?> superClass = args[i].getClass().getSuperclass();
            while (superClass != null) {
                // 如果我们传入的值是方法上声明的参数的子类,那么每多一层继承关系,差异值加2
                if (paramType.equals(superClass)) {
                    result = result + 2;
                    superClass = null;
                }
                else if (ClassUtils.isAssignable(paramType, superClass)) {
                    result = result + 2;
                    superClass = superClass.getSuperclass();
                }
                else {
                    superClass = null;
                }
            }
            // 判断方法的参数是不是一个接口,如果是,那么差异值加1
            if (paramType.isInterface()) {
                result = result + 1;
            }
        }
    }
    return result;
}

严格模式:

public int getAssignabilityWeight(Class<?>[] paramTypes) {
    // 严格模式下,只有三种返回值
    // 1.Integer.MAX_VALUE,经过类型转换后还是不符合要求,返回最大的类型差异
    // 因为解析后的参数可能返回一个NullBean(创建对象的方法返回了null,Spring会将其包装成一个NullBean),不过一般不会出现这种情况,所以我们可以当这种情况不存在
   for (int i = 0; i < paramTypes.length; i++) {
    if (!ClassUtils.isAssignableValue(paramTypes[i], this.arguments[i])) {
     return Integer.MAX_VALUE;
    }
   }
    // 2.Integer.MAX_VALUE - 512,进行过了类型转换才符合要求
   for (int i = 0; i < paramTypes.length; i++) {
    if (!ClassUtils.isAssignableValue(paramTypes[i], this.rawArguments[i])) {
     return Integer.MAX_VALUE - 512;
    }
   }
    // 3.Integer.MAX_VALUE - 1024,没有经过类型转换就已经符合要求了,返回最小的类型差异
   return Integer.MAX_VALUE - 1024;
  }
上一篇下一篇

猜你喜欢

热点阅读