基于AnnotationConfigApplicationContext的Bean加载过程(Spring Version 5.2.0)

建立个实体类

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Book {

    private String name;

    public Book(String name) {
        this.name = name;
    }
}

再建立个配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BookConfig {
    @Bean
    public Book book(){
        return new Book("BBB");
    }
}

最后是启动程序

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(BookConfig.class);
        Book book = context.getBean(Book.class);
        System.out.println(book);
    }

}

主要看getBean的过程

1. 首先进入org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.Class<T>)

2. 进入org.springframework.context.support.GenericApplicationContext#getBeanFactory

3. 进入org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>)

实际上调用的是重载方法getBean,在其中调用的是resolveBean方法,解析bean。

==========================================对比==========================================

等一等??看网上其它教程都会有个doGetBean的东西,到这里怎么没有了?

我们知道目前常见的创建Application的方式有三种

FileSystemXmlApplicationContext/ClassPathXmlApplicationContext/AnnotationConfigApplicationContext

你以为我想说和上下文类型有关系?但是我告诉你和应用上下文的类型是没有任何关系的!这三种主要的区别就是读取配置的来源不同罢了,内部调用的都是refresh方法。

真正导致调用的方法不同,取决于你调用的是AbstractApplicationContext#getBean的哪一个重载方法。

第一个参数为String类型的getBean方法,最终会调用的AbstractBeanFactory#doGetBean

第一个参数为Class类型的getBean方法,最终会调用的DefaultListableBeanFactory#resolveBean

另外,你以为这两个方法没有关系?错了,最终resolveBean会义无反顾的调用doGetBean方法。这也可以看出,无论版本迭代多么快,核心代码是不会轻易变动的

如红框的会跑到AbstractBeanFactory类里

蓝框的跑到DefaultListableBeanFactory类里

4. 根据传入的Class,先封装成ResolvableType。(对于指定的Class,返回一个ResolvableType,仅对原始类执行可分配性检查,这是一个包装器。)

5. 带着ResolveableType进入org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveBean

@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    // 根据传入的ResolvableType,返回一个NamedBeanHolder(一个持有bean名称和bean实例的容器)
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
    // 如果namedBean不为空,则直接返回实例
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
    // namedBean为空(比如我获取了一个不存在的bean)则执行以下内容↓

    // 获取父bean工厂
    BeanFactory parent = getParentBeanFactory();
    // 如果是DefaultListableBeanFactory的实例,则正常解析
    if (parent instanceof DefaultListableBeanFactory) {
        return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
    }
    // 不是DefaultListableBeanFactory的实例并且不为空(这一步具体干啥还不清楚)
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
        }
    }
    // parent也为空,则返回空
    return null;
}

这个方法呢,主要调用了resolveNamedBean方法,利用返回持有名称和实例的容器获得bean实例。不是核心方法。

6. org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveNamedBean(org.springframework.core.ResolvableType, java.lang.Object[], boolean)

这个方法干的事情就比较多了

@SuppressWarnings("unchecked")
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
        ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
    Assert.notNull(requiredType, "Required type must not be null");
    // 根据类型获取bean名称---①
    String[] candidateNames = getBeanNamesForType(requiredType);

    // 如果bean名称不止一个(比如你定义了多个同类型但是名称不一样的Bean)
    if (candidateNames.length > 1) {
        // 自动装配候选者列表
        List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
        // 遍历bean名称
        for (String beanName : candidateNames) {
            // 判断:如果beanDefinitionMap不包含key为beanName的键值对或者该bean可以被自动装配到其他bean中。则添加到候选列表中
            if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
                autowireCandidates.add(beanName);
            }
        }
        // 候选列表不为空,则给候选名称重新赋值
        if (!autowireCandidates.isEmpty()) {
            candidateNames = StringUtils.toStringArray(autowireCandidates);
        }
    }
    // bean名称只有一个
    if (candidateNames.length == 1) {
        // 因为只有一个,所以是0下标的名称
        String beanName = candidateNames[0];
        // 返回一个持有bean名称和bean实例的容器【getBean方法:绕了一圈,依然回到了AbstractBeanFactory#getBean,准确来说是doGetBean方法】---②
        return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
    }
    else if (candidateNames.length > 1) {
        Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
        // 遍历候选名称
        for (String beanName : candidateNames) {
            // 如果是单例并且args为空
            if (containsSingleton(beanName) && args == null) {
                // getBean实例化bean【getBean方法:绕了一圈,依然回到了AbstractBeanFactory#getBean,准确来说是doGetBean方法】
                Object beanInstance = getBean(beanName);
                // 放进候选Map里,value是bean实例
                candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
            }
            else {
                // 否则直接范进Map里,value是bean的Class
                candidates.put(beanName, getType(beanName));
            }
        }
        // 因为这个方法只能返回一个实例,而这种情况我们获取了多个,到底返回哪一个?
        // 这一步:确定给定bean集合中的主要候选对象。---③
        String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
        if (candidateName == null) {
            // 这一步:确定给定bean集合中具有最高优先级的对象。---④
            candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
        }
        // 如果确定了返回哪一个对象
        if (candidateName != null) {
            // 从候选集合中选出目标对象
            Object beanInstance = candidates.get(candidateName);
            // 没有实例化则实例化
            if (beanInstance == null || beanInstance instanceof Class) {
                beanInstance = getBean(candidateName, requiredType.toClass(), args);
            }
            // 返回包装类
            return new NamedBeanHolder<>(candidateName, (T) beanInstance);
        }
        // 前面都没确定出来,那只能抛异常了。
        if (!nonUniqueAsNull) {
            // 比如:No qualifying bean of type 'com.demo.tools.Book' available: expected single matching bean but found 2
            throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
        }
    }
    return null;
}

总结:

1. 根据传入的类型获取bean的所有名称。

2. 过滤候选bean名称。

3. 如果bean名称只有一个,那么直接调用AbstractBeanFactory里的doGetBean进行实例化并返回。

3. 如果bean名称有多个,则选出主要候选名称或者最高优先级的名称来帮助实例化。如果没有选出可用的名称,则抛出bean定义冲突异常。

下面看一下其它方法:

①:根据类型获取名称列表

@Override
public String[] getBeanNamesForType(ResolvableType type) {
    return getBeanNamesForType(type, true, true);
}
@Override
public String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    Class<?> resolved = type.resolve();
    // 如果resolved不为空,并且不是泛型参数
    if (resolved != null && !type.hasGenerics()) {
        // 虽然调用了这个方法,但是这个方法实际上调用的也是doGetBeanNamesForType
        return getBeanNamesForType(resolved, includeNonSingletons, includeNonSingletons);
    }
    else {
        return doGetBeanNamesForType(type, includeNonSingletons, includeNonSingletons);
    }
}

@Override
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
    // 正常来讲不会走这里,这里是什么情况??
    if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
        return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
    }
    // 先从缓存中找
    Map<Class<?>, String[]> cache =
            (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
    String[] resolvedBeanNames = cache.get(type);
    if (resolvedBeanNames != null) {
        return resolvedBeanNames;
    }
    // 缓存没有,则创建,并放到缓存中
    resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
    if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
        cache.put(type, resolvedBeanNames);
    }
    return resolvedBeanNames;
}

// NamedBeanHolder:持有beanName和beanInstance的包装类
// BeanDefinitionHolder:包含名称和别名以及bean定义的Holder。可以注册为内部bean的占位符。
// 重点类:RootBeanDefinition、DefaultSingletonBeanRegistry
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    List<String> result = new ArrayList<>();

    // 检查全部的bean定义
    for (String beanName : this.beanDefinitionNames) {
        // 只有当bean名称没有定义为其他bean的别名时,才认为bean是合格的
        if (!isAlias(beanName)) {
            try {
                // 返回合并的RootBeanDefinition,如果指定的bean符合子bean定义,则遍历父bean定义。【为什么要合并定义?后面会讲】
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 只有在bean定义完成时才检查它。
                if (!mbd.isAbstract() && (allowEagerInit ||
                        (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                                !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                    // 检查给定的bean是否定义为FactoryBean。
                    boolean isFactoryBean = isFactoryBean(beanName, mbd);
                    // 返回由这个bean定义修饰的目标定义
                    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                    boolean matchFound = false;
                    // 允许FactoryBean初始化(allowEagerInit==true 或者 这个bean是单例bean)
                    boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
                    // 
                    boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
                    // 不是FactoryBean
                    if (!isFactoryBean) {
                        if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                            // 检查给定名称的bean是否与指定的类型匹配。允许应用额外的约束,以确保不过早地创建bean。
                            // 注意这个isTypeMatch方法是@since 5.2新加的,内容过多,暂且不谈
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                    }
                    // 是FactoryBean
                    else  {
                        if (includeNonSingletons || isNonLazyDecorated ||
                                (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                        // 不匹配
                        if (!matchFound) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            beanName = FACTORY_BEAN_PREFIX + beanName;
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                    }
                    // 只有匹配的才会记录下来
                    if (matchFound) {
                        result.add(beanName);
                    }
                }
            }
            catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
                if (allowEagerInit) {
                    throw ex;
                }
                // Probably a placeholder: let's ignore it for type matching purposes.
                LogMessage message = (ex instanceof CannotLoadBeanClassException) ?
                        LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
                        LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);
                logger.trace(message, ex);
                onSuppressedException(ex);
            }
        }
    }


    // 检查手动注册的单例。
    for (String beanName : this.manualSingletonNames) {
        try {
            // 对于FactoryBean,匹配FactoryBean创建的对象。【org.springframework.beans.factory.FactoryBean】(FactoryBean后面也会讲)
            if (isFactoryBean(beanName)) {
                if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
                    result.add(beanName);
                    // 已经匹配过这个bean,跳过
                    continue;
                }
                // 对于FactoryBean,接下来尝试匹配FactoryBean本身。
                beanName = FACTORY_BEAN_PREFIX + beanName;
            }
            // 匹配原始bean实例(可能是原始的FactoryBean)。
            if (isTypeMatch(beanName, type)) {
                result.add(beanName);
            }
        }
        catch (NoSuchBeanDefinitionException ex) {
            // Shouldn't happen - probably a result of circular reference resolution...
            logger.trace(LogMessage.format("Failed to check manually registered singleton with name '%s'", beanName), ex);
        }
    }

    return StringUtils.toStringArray(result);
}

这么多逻辑,无非作者考虑的很周全,实际上只是一个根据类型获取bean名称的过程。另外你还能发现Spring的命名特点,getXXX方法仅仅是做了一些准备工作,真正工作的是doGetXXX方法。

②:doGetBean方法

 这个方法比较复杂,涉及到其它的方法也很多,所以我在后面单独一部分讲解,麻烦移步后面。

③:获取主要候选名称

protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
    String primaryBeanName = null;
    // 遍历候选名称集合
    for (Map.Entry<String, Object> entry : candidates.entrySet()) {
        String candidateBeanName = entry.getKey();
        Object beanInstance = entry.getValue();
        // 如果是主要候选对象。这里返回bean定义里的primary对象的值,具体来说就是如果你定义bean的时候用@Primary注解标注的,则是true
        if (isPrimary(candidateBeanName, beanInstance)) {
            // 因为是循环所有的候选名称,第一次primaryBeanName肯定是null,所以在else语句给它赋值。如果出现了多个Primary注解的bean,那就会抛出异常
            if (primaryBeanName != null) {
                boolean candidateLocal = containsBeanDefinition(candidateBeanName);
                boolean primaryLocal = containsBeanDefinition(primaryBeanName);
                if (candidateLocal && primaryLocal) {
                    throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
                            "more than one 'primary' bean found among candidates: " + candidates.keySet());
                }
                else if (candidateLocal) {
                    primaryBeanName = candidateBeanName;
                }
            }
            else {
                primaryBeanName = candidateBeanName;
            }
        }
    }
    return primaryBeanName;
}

总结:如果出现了多个候选名称,则会选出被@Primary注解标注的bean。如果出现多个@Primary的bean,依然会抛出异常。

④:获取最高优先级名称

protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
    String highestPriorityBeanName = null;
    Integer highestPriority = null;
    for (Map.Entry<String, Object> entry : candidates.entrySet()) {
        String candidateBeanName = entry.getKey();
        Object beanInstance = entry.getValue();
        if (beanInstance != null) {
            // 获取优先级,通过Primary的例子,这个也可以猜出是标记了@Priority注解,数字越小优先级越高。
            // @Priority注解需要单独引入依赖:

            // <dependency>
            //     <groupId>javax.annotation</groupId>
            //     <artifactId>javax.annotation-api</artifactId>
            //     <version>1.3.2</version>
            // </dependency>

            Integer candidatePriority = getPriority(beanInstance);
            if (candidatePriority != null) {
                if (highestPriorityBeanName != null) {
                    if (candidatePriority.equals(highestPriority)) {
                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(),
                                "Multiple beans found with the same priority ('" + highestPriority +
                                "') among candidates: " + candidates.keySet());
                    }
                    else if (candidatePriority < highestPriority) {
                        highestPriorityBeanName = candidateBeanName;
                        highestPriority = candidatePriority;
                    }
                }
                else {
                    highestPriorityBeanName = candidateBeanName;
                    highestPriority = candidatePriority;
                }
            }
        }
    }
    return highestPriorityBeanName;
}

主要方法调用流程

核心方法依然是org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

先看一下重点步骤,然后分步解释

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

    // 1. 转换bean名称
    final String beanName = transformedBeanName(name);
    Object bean;

    // 2. 检查单例缓存中手动注册的单例对象
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 3. 获取给定bean实例的对象,可能是它本身,也可能是FactoryBean创建的对象。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // 如果指定的原型bean正在创建,则抛出异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 获取父工厂
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 当前工厂里不存在这个bean定义则在父工厂里面找
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // 获取原始bean名称
            String nameToLookup = originalBeanName(name);
            // 下面都是递归寻找过程
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
            }
            else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
            else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        // 不仅仅做类型检查,还要创建,则要先记录下来
        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        // 下面就是创建的过程了

        try {
            // 4. 合并bean定义,拿到RootBeanDefinition
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 检查bean定义
            checkMergedBeanDefinition(mbd, beanName, args);

            // 保证当前bean所依赖的bean的初始化。
            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 + "'");
                    }
                    // 5. 给当前bean注册一个依赖bean
                    registerDependentBean(dep, beanName);
                    try {
                        // 递归实例化依赖
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 6. 创建单实例bean
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, () -> {
                    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);
            }

            // 7. 创建多实例bean
            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 {
                // 8. 在指定的scope上实例化bean
                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, () -> {
                        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;
        }
    }

    // 9. 检查所需的类型是否与实际bean实例的类型相匹配。
    if (requiredType != null && !requiredType.isInstance(bean)) {
        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名称。

2. 查看缓存中有没有,有则直接返回。

3. 缓存没有,先找到并确定bean定义。

4. 合并bean定义。

5. 检查循环依赖。

6. 根据配置,创建单实例bean还是多实例bean还是scope范围的bean。

7. 做最后的类型检查,无误后返回。

下面分步骤

1. 转换bean名称。

protected String transformedBeanName(String name) {
    // beanName转换分两部分,一个是去掉工厂的取消引用前缀;一个是将别名解析为规范名称。
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

// 返回实际的bean名称,去掉工厂的取消引用前缀(如果有,也去掉重复的工厂前缀)
public static String transformedBeanName(String name) {
    Assert.notNull(name, "'name' must not be null");
    if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
        return name;
    }
    return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
        do {
            beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
        }
        while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));   // 只要发现beanName以&开头,就会去除&,所以你就算写一百个&也不会有错误。
        return beanName;
    });
}

// 确定原始名称,将别名解析为规范名称。
public String canonicalName(String name) {
    String canonicalName = name;
    // Handle aliasing...
    String resolvedName;
    do {
        // 根据传入的名称,从别名Map里查询
        resolvedName = this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
            canonicalName = resolvedName;
        }
    }
    while (resolvedName != null);
    return canonicalName;
}

这里涉及两个扩展内容,第一个就是FactoryBean,第二个就是别名。

BeanFactory和FactoryBean?

BeanFactory是顶级接口,是IDC容器实现的基础。

FactoryBean是为用户准备的,用来实例化一些复杂的Bean,给上层应用带来便利。

来看个例子,重新修改配置类的内容,加入了一个FactoryBean,以及定义了别名。

import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BookConfig {

    @Bean(name = {"第一个是原始名称", "book", "tom", "cat"})
    public BookFactoryBean book(){
        BookFactoryBean bookFactoryBean = new BookFactoryBean();
        bookFactoryBean.setBeanInfo("它们隐藏了实例化一些复杂bean 的细节,给上层应用带来了便利");
        return bookFactoryBean;
    }
    
}

class BookFactoryBean implements FactoryBean<Book>{

    private String beanInfo;

    @Override
    public Book getObject() throws Exception {
        return new Book("AAA");
    }

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

    public String getBeanInfo() {
        return beanInfo;
    }

    public void setBeanInfo(String beanInfo) {
        this.beanInfo = beanInfo;
    }
}

运行程序代码

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(BookConfig.class);
//        Book book = context.getBean(Book.class);
        Object bean = context.getBean("&&&book");
        Object bean1 = context.getBean("第一个是原始名称");
        Object bean2 = context.getBean("cat");
        System.out.println(bean);
        System.out.println(bean1);
        System.out.println(bean2);
    }

}

输出结果:

第一个问题:beanName前面加个&,代表获取FactoryBean。

第二个问题:无论用什么名称,在内部都会找到它的原始名称。

根据debug的结果可以看出:定位bean还是需要原始名称,如果传入的是原始名称,则直接返回。

总结:

转换beanName包含两部分:一个是去掉工厂的&前缀,另一个是利用AliasMap找到Bean的原始名称。

2. 检查单例缓存

这个方法在另一个类里:DefaultSingletonBeanRegistry#getSingleton(java.lang.String)

public Object getSingleton(String beanName) {
    // allowEarlyReference 为true
    return getSingleton(beanName, true);
}

// 根据名称找到注册的(原始)单例对象。
// 检查已经实例化的单例并允许对当前单例的早期引用(解析循环引用)。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 这里获得的可能是bean也可能是FactoryBean
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果没有获取到并且发现当前bean正在创建
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 从早期单例对象缓存中尝试获取,有的话返回
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 如果从早期单例对象缓存中没有获取的,并且允许早期依赖
            if (singletonObject == null && allowEarlyReference) {
                // 则获取单例工厂
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    // 用工厂方法创建实例
                    singletonObject = singletonFactory.getObject();
                    // 放进早期单例对象缓存中
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 移除工厂缓存中的bean
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    // 只要获取到,即返回
    return singletonObject;
}

这其中涉及了三个缓存

/** 单例对象缓存: beanName -> beanInstance. 存放创建完成的bean */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** 单例工厂缓存: beanName -> ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** 早期单例对象缓存: beanName -> beanInstance. 已经实例化但是还没有创建完成的单例bean被放到这里面,其目的是用来检测循环引用 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** 已经注册的bean放在这里. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);


获取过程很简单:先去缓存中寻找,缓存中没有去早期缓存中找,早期缓存没有则获取单例工厂,利用工厂方法获取实例,并添加到早期缓存中,同时移除工厂缓存中的bean。最后返回。

对于Spring解决循环依赖的问题:

Spring只能解决单例模式下的Setter循环依赖,Spring不能解决prototype作用域的bean之间的循环依赖。
Spring在获取ClassA的实例时,不等ClassA完成创建就将其曝光加入正在创建的bean缓存中。
在解析ClassA的属性时,又发现依赖于ClassB,再次去获取ClassB,当解析ClassB的属性时,又发现需要ClassA的属性,
但此时的ClassA已经被提前曝光加入了正在创建的bean的缓存中,则无需创建新的的ClassA的实例,直接从缓存中获取即可。从而解决循环依赖问题。

另外:根据代码逻辑不难发现,ClassA实例化的时候发现需要依赖ClassB,于是把ClassA先缓存起来,去实例化ClassB。也就是说,优先初始化最底层对象

根据Debug的结果,这一步可能获取到的是个FactoryBean:

3. 获取真正实例对象getObjectForBeanInstance

因为上一步的过程,我们可以知道,返回结果不一定是我们需要的对象。

/**
 * org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getObjectForBeanInstance
 * 
 * @since 5.0
 * @see #obtainFromSupplier
 */
@Override
protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    // 获取当前ThreadLocal存储的变量,也就是当前正在创建的bean
    String currentlyCreatedBean = this.currentlyCreatedBean.get();
    if (currentlyCreatedBean != null) {
        // 如果当前有正在创建的bean,则注册为beanName所依赖的bean
        registerDependentBean(beanName, currentlyCreatedBean);
    }
    return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    // 根据name判断我们需要的是不是FactoryBean(判断名字里有没有&)
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        // 返回FactoryBean实例
        return beanInstance;
    }
    // 走到这里,证明我们需要的是bean实例,而不是FactoryBean实例。而到这里beanInstance可能是个bean,也可能是个FactoryBean。
    // 如果它是一个FactoryBean,我们将使用它来创建一个bean实例
    if (!(beanInstance instanceof FactoryBean)) {
        // 不是FactoryBean,直接返回即可。
        return beanInstance;
    }
    Object object = null;
    if (mbd != null) {
        mbd.isFactoryBean = true;
    }
    else {
        // 根据beanName,从FactoryBean缓存中获取FactoryBean
        object = getCachedObjectForFactoryBean(beanName);
    }
    // FactoryBean缓存中没找到目标
    if (object == null) {
        // 把当前的beanInstance强制转换成FactoryBean
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // RootBeanDefinition为空并且beanDefinitionMap中包含次beanName
        if (mbd == null && containsBeanDefinition(beanName)) {
            // 合并bean定义,返回一个RootBeanDefinition
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        // 代表RootBeanDefinition是否是合成得到的
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        // 从FactoryBean中获取bean实例
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

这部分的主要逻辑是:

1. 根据name判断我们需要的是个Bean实例还是FactoryBean实例。

2. 如果需要FactoryBean实例,则做一些校验后返回上一步得到的对象。

2. 如果需要Bean实例,则判断上一步返回的对象是不是个纯粹的Bean,是则返回;如果是个FactoryBean实例,则用FactoryBean创建一个Bean实例返回。

这部分涉及一个从FactoryBean中获取bean实例的过程:

// org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    // 是单例并且单例缓存中有此beanName的key
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            // 先检查缓存,这个factoryBeanObjectCache存储的是由FactoryBean创建的单例对象的缓存。key为FactoryBean名称。
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                // factoryBeanObjectCache缓存没有,则执行FactoryBean的getObject方法,获取bean实例
                object = doGetObjectFromFactoryBean(factory, beanName);
                // 考虑循环依赖的情况
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {
                    // 后置处理
                    if (shouldPostProcess) {
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // Temporarily return non-post-processed object, not storing it yet..
                            return object;
                        }
                        // 单例创建之前,将单例对象注册为当前正在创建的状态(添加到singletonsCurrentlyInCreation里)
                        beforeSingletonCreation(beanName);
                        try {
                            // 在初始化之后应用后置处理
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                    "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            // 最后将单例对象正在创建的状态移除(从singletonsCurrentlyInCreation里移除)
                            afterSingletonCreation(beanName);
                        }
                    }
                    // 因为是FactoryBean创建的bean,所以添加到对应的缓存里
                    if (containsSingleton(beanName)) {
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            // // 返回结果
            return object;
        }
    }
    // 不是单例或者缓存中没有此beanName
    else {
        // 调用factory的getObject方法获取实例bean
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        // 执行后置处理
        if (shouldPostProcess) {
            try {
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        // 返回结果
        return object;
    }
}

简单来讲:

1. 先从factoryBeanObjectCache缓存中查看是否存在此FactoryBean创建的单例,有则返回,没有的话执行FactoryBean的getObject方法来获取;

2. 获取完进行后置处理,后置处理之前将次beanName添加到 singletonsCurrentlyInCreation 集合中以示正在创建中,后置处理之后将beanName从 singletonsCurrentlyInCreation 集合中移除,以清除正在创建状态。

4. 这部分涉及了一个合并BeanDefinition的过程。关于BeanDefinition的结构如下:

-

待续

5. 注册依赖Bean

/** 别人依赖我:key=我,value=依赖我的人 */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** 我依赖别人:key=我,value=我依赖的人 */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

// beanName依赖dep
registerDependentBean(dep, beanName);

// beanName-被依赖者;dependentBeanName-依赖者
public void registerDependentBean(String beanName, String dependentBeanName) {
    String canonicalName = canonicalName(beanName);
    // 别人依赖我:key=beanName,value=Set(dependentBeanName)
    synchronized (this.dependentBeanMap) {
        Set<String> dependentBeans =
                this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
        if (!dependentBeans.add(dependentBeanName)) {
            return;
        }
    }
    // 我依赖别人:key=dependentBeanName,value=Set(beanName)
    synchronized (this.dependenciesForBeanMap) {
        Set<String> dependenciesForBean =
                this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
        dependenciesForBean.add(canonicalName);
    }
}

这个依赖关系有点绕,要仔细一点捋一下。

dependentBeanMap:dependent【依赖】Bean【我】Map,key是被依赖者,value是依赖者
dependenciesForBeanMap:dependencies【依赖项】For【给】Bean【我】Map,key是依赖者,value是被依赖者

不知道我这样解释能不能明白这个关系?

6. 创建单实例bean

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;

    // 确保此时bean已经解析,并在动态解析的类不能存储在共享的合并bean定义中时,克隆bean定义。【根据Bean定义解析BeanClass】
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    try {
        // 验证&准备在该bean中定义的覆盖的方法。
        // 检查是否存在具有指定名称的方法。
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // 给 Bean后置处理器 一个机会,返回一个目标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);
    }
}

这个方法主要有三步:

1. 解析BeanClass

2. 验证&准备Bean定义中覆盖的方法

3. 执行创建Bean

来看doCreateBean

// 【执行创建bean的具体逻辑】
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

    // BeanWrapper是个Bean包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // ☆☆☆【实例化Bean】
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    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);
            }
            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);
        // ☆☆☆【初始化Bean实例】
        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<>(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.");
                }
            }
        }
    }

    // 将bean注册为一次性的
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

这部分同样也主要分为三步,同时这也是Bean生命周期的体现

1. ☆☆☆【实例化Bean】

2. ☆☆☆【属性赋值】

3. ☆☆☆【初始化Bean实例】

4. ☆☆☆【销毁】(销毁在这里没有体现)

☆☆☆【实例化Bean】☆☆☆

// 通过适当的策略实例化Bean:工厂方法、构造方法自动装配或者简单实例化
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());
    }
    // 获取创建bean实例的回调
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        // 利用instanceSupplier获取一个Bean实例
        return obtainFromSupplier(instanceSupplier, beanName);
    }
    // 如果工厂方法不为空
    if (mbd.getFactoryMethodName() != null) {
        // 通过工厂方法实例化Bean(详见:org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod)
        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) {
            // 构造方法自动装配(详见:org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor)
            return autowireConstructor(beanName, mbd, null, null);
        }
        // 否则是普通的实例化
        else {
            return instantiateBean(beanName, mbd);
        }
    }
    // 返回用于给定bean的候选构造函数,检查所有已注册的构造函数
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 构造方法自动装配(详见:org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor)
        return autowireConstructor(beanName, mbd, ctors, args);
    }
    // 如果有默认的构造函数
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // 没有特殊的处理器,使用无参构造函数
    return instantiateBean(beanName, mbd);
}

这个方法主要是选取适当的策略来决定如何创建Bean

1. 利用Bean定义中的instanceSupplier获取Bean

2. 利用指定的工厂方法名称实例化Bean

3. 利用构造方法自动装配实例化Bean

4. 简单的使用无参构造函数实例化Bean,这个也是默认的处理方式

选择默认处理方式:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());
        }
        else {
            // org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        // 新建一个Bean包装类
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        // 初始化Bean包装类
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

这个方法描述了两个主要步骤

1. 实例化Bean

2. 新建 & 初始化包装类,并返回。

看实例化

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // 如果没有覆盖的方法,则不使用CGLIB覆盖
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                // 获取Class对象
                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(
                                (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        // 获取Constructor对象
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    // 给RootBeanDefinition设置已解析的构造函数或工厂方法
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        // 工具类,实例化Bean(绕了这么多,真正干活的是这个方法)
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        // 子类可以覆盖这个方法,如果子类可以用给定的RootBeanDefinition中指定的方法注入实例化一个对象。实现该方法的目的是抛出UnsupportedOperationException。
        // 实例化应该使用无参数的构造函数。
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
        // 反射方法(ctor.setAccessible(true);)
        ReflectionUtils.makeAccessible(ctor);
        if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
            return KotlinDelegate.instantiateClass(ctor, args);
        }
        else {
            // 获得参数类型
            Class<?>[] parameterTypes = ctor.getParameterTypes();
            // 参数数量校验
            Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
            Object[] argsWithDefaultValues = new Object[args.length];
            // 组装参数
            for (int i = 0 ; i < args.length; i++) {
                if (args[i] == null) {
                    Class<?> parameterType = parameterTypes[i];
                    argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
                }
                else {
                    argsWithDefaultValues[i] = args[i];
                }
            }
            // 反射方法,利用给定的参数new一个实例
            return ctor.newInstance(argsWithDefaultValues);
        }
    }
    catch (InstantiationException ex) {
        throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
    }
    catch (IllegalAccessException ex) {
        throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
    }
    catch (IllegalArgumentException ex) {
        throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
    }
    catch (InvocationTargetException ex) {
        throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
    }
}

实际上实例化的方法并不复杂,复杂的是前期准备的过程

实例化的过程:组装参数成一个Object数组(无参的话数组长度为0),传入Constructor的newInstance方法完成实例化。

实例化全程总结:

1. 根据情况选取合适的创建策略

  ☆ 利用Bean定义中的instanceSupplier获取Bean

  ☆ 利用指定的工厂方法名称实例化Bean

  ☆ 利用构造方法自动装配实例化Bean

  ☆ 简单的使用无参构造函数实例化Bean,这个也是默认的处理方式

2. 将实例封装成一个包装类

  ☆ 通过反射方法实例化Bean

  ☆ 新建 & 初始化Bean的包装类

另外:我看了下利用工厂方法创建和构造方法自动装配两种方式,除了过程比较复杂,其实例化的时候调用的都是org.springframework.beans.factory.support.ConstructorResolver#instantiate(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object, java.lang.reflect.Method, java.lang.Object[])

进而调用org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory, java.lang.Object, java.lang.reflect.Method, java.lang.Object...)

刚好和上面对上,实例化都是利用反射(当然这样说也不是很严谨),因为实例化策略的实现有两个,除了反射还有CGLIB,如图:

☆☆☆【属性赋值】☆☆☆

// ☆☆☆【属性赋值】
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // Bean实例为空的不用属性赋值
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // 给任何一个InstantiationAwareBeanPostProcessor在属性设置之前修改bean状态的机会。
    boolean continueWithPropertyPopulation = true;

    // 如果Bean定义不是合成的,并且,当前的工厂持有InstantiationAwareBeanPostProcessor列表
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        // 遍历用于此工厂创建bean的beanpostprocessor列表
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            // 如果当前Processor是InstantiationAwareBeanPostProcessor的子类实现
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 如果不是实例化之后的处理器,则设置continueWithPropertyPopulation为false,目的不再执行后续属性设置
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }
    // 注:InstantiationAwareBeanPostProcessor出现在Bean实例化前后,属性(自动装配)之前。

    // 根据上面的执行结果,决定是否还要继续
    if (!continueWithPropertyPopulation) {
        return;
    }

    // 尝试获取Bean定义里的属性值映射列表
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // 获取解析到的自动装配模式
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    // 如果是根据名称自动装配或者根据类型自动装配,这里仅仅是将属性名称-属性值的映射关系装配到PropertyValues对象中
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 当前的工厂是否持有InstantiationAwareBeanPostProcessor列表
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否需要检查依赖
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    // 如果当前的工厂持有InstantiationAwareBeanPostProcessor列表
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        // 遍历执行处理器,对属性进行后置处理
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    // 需要检查依赖
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        // 检查依赖
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    // 最后,如果属性值列表不为空
    if (pvs != null) {
        // 设置属性
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

大概流程是

1. 进行Bean实例化之后的后置处理。

2. 先获取默认的属性映射关系对象,然后根据模式判断按照名称还是按照类型自动装配。

3. 遍历后置处理器,对装配好的属性映射关系对象进行后置处理。

4. 检查依赖。

5. 属性赋值。

另:autowireByName/autowireByType/applyPropertyValues这三个方法暂时不提,太多了。

☆☆☆【初始化Bean实例】☆☆☆

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

// ☆☆☆【初始化Bean实例】
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        // 1. 执行Aware子类相关的方法
        invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 2. 初始化之前的后置处理
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
        // 3. 执行初始化方法
        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()) {
        // 4. 初始化之后的后置处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

1. Aware的子类

private void invokeAwareMethods(final String beanName, final Object bean) {
    // Aware是个顶级标记接口,作用是能够感知自己的一些属性。示例在后面单独说明。
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

2、3 . 初始化前后的处理

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 遍历后置处理器,调用初始化之前的后置处理方法
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 遍历后置处理器,调用初始化之后的后置处理方法
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

4. 初始化方法

// 初始化
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    boolean isInitializingBean = (bean instanceof InitializingBean);
    // 这个Bean实现了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 {
            // 因为InitializingBean接口里只有一个afterPropertiesSet方法,所以这个是由子类实现的方法。
            // 作用顾名思义,在属性赋值之后做的一些善后工作。该方法允许bean实例在设置了所有bean属性后执行总体配置验证和最终初始化。
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }
    // 如果配置了比如:@Bean(initMethod = "myInit"),指定了自定义的初始化方法,就会在这个时候执行
    if (mbd != null && bean.getClass() != NullBean.class) {
        // 获取初始化方法名称
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 这里内部实现是利用反射执行初始化方法的
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

示例

定义一个Bean

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;

@Getter
@Setter
public class Apple implements BeanNameAware,InitializingBean {

    private String id;
    private String name;

    // 对于Aware接口的子类,实现了的方法会在Bean的初始化阶段被调用
    public void setBeanName(String name) {
        this.id = name;
    }

    // 对于实现InitializingBean接口的Bean,需要实现这个方法,目的是属性赋值之后做的一些善后工作
    public void afterPropertiesSet() throws Exception {
        System.out.println("Do Anything");
        this.name = "我这里设置了属性B";
    }

    // 自定义的Bean初始化方法
    public void myInitMethod(){
        System.out.println("Do Something");
    }
}

配置类

import com.entity.Apple;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

    @Bean(initMethod = "myInitMethod")
    public Apple apple(){
        Apple apple = new Apple();
        apple.setName("我这里设置了属性A");
        return apple;
    }
}

运行

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String[] args){
        ApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
    }
}

如果你打断点,你会在这里拦截到我们配置影响的第一个点【Aware接口

进入方法,会执行我们定义的setBeanName方法(这样,我们实现了BeanNameAware接口的Bean就能获取到自己的Bean名称

----------------

接下来到第二个部分(InitializingBean接口

进入方法,先执行我们定义的  afterPropertiesSet

----------

然后到第三部分,执行我们定义的自定义初始化方法。

初始化部分总结:

1. 如果Bean实现了Aware接口,则会执行其中的方法(方法只有一个)。实际应用比如:写一个实现ApplicationContextAware接口的工具类,来获取当前应用程序上下文。进而手动getBean。

2. 执行初始化之前的后置处理器。

3. 初始化:① 如果Bean实现了 InitializingBean 接口,则会执行 afterPropertiesSet。 ② 如果Bean指定了自定义的初始化方法,则会执行此方法。

4. 执行初始化之后的后置处理器。

思考:如果只是一个普通的Bean,则不会执行这么多逻辑。这些额外的处理都是为了应付一些复杂的场景,这里也能体会到作者的用意——扩展性。

☆☆☆【总结:Bean实例化过程,主要过程全部体现在AbstractAutowireCapableBeanFactory类里】☆☆☆

☆☆☆【销毁Bean】☆☆☆

如果前面创建单例出现了异常,就会执行销毁操作。

if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, () -> {
        try {
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            // 显式地从单例缓存中删除实例:它可能被创建过程提前暴露放在那里,以允许循环引用解析。
            // 还要删除所有接受该bean临时引用的bean。
            destroySingleton(beanName);
            throw ex;
        }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

如果你想打断点到这一行,只需要在Apple实体类里加一句话:

打断点能捕获到

// 先执行:org.springframework.beans.factory.support.DefaultListableBeanFactory#destroySingleton
public void destroySingleton(String beanName) {
    // 执行父类的逻辑
    super.destroySingleton(beanName);
    // 更新manualSingletonNames集合,从中删除beanName
    removeManualSingletonName(beanName);
    // 清除所有按照Type获取的BeanName缓存【this.allBeanNamesByType.clear(); this.singletonBeanNamesByType.clear();】
    clearByTypeCache();
}

父类逻辑

// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton
public void destroySingleton(String beanName) {
    // 删除所有此beanName注册的Bean缓存(singletonObjects、singletonFactories、earlySingletonObjects、registeredSingletons)
    removeSingleton(beanName);
    // 销毁相应的DisposableBean实例
    DisposableBean disposableBean;
    synchronized (this.disposableBeans) {
        // 从存储一次性Bean的LinkedHashMap集合中删除此beanName
        disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
    }
    // 执行删除
    destroyBean(beanName, disposableBean);
}

destroyBean

protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
    // Trigger destruction of dependent beans first...
    Set<String> dependencies;
    synchronized (this.dependentBeanMap) {
        // Within full synchronization in order to guarantee a disconnected Set
        // 从依赖Map中移除并获取依赖此bean的集合
        dependencies = this.dependentBeanMap.remove(beanName);
    }
    if (dependencies != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
        }
        // 如果存在依赖,则递归删除所有依赖这个beanName的所有bean
        // 这个地方白话解释一下:母猫死亡(发生了异常),那么母猫影响的是所有依赖母猫的小猫(Bean)
        for (String dependentBeanName : dependencies) {
            destroySingleton(dependentBeanName);
        }
    }

    // Actually destroy the bean now...
    // 删除一次性的bean
    if (bean != null) {
        try {
            bean.destroy();
        }
        catch (Throwable ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
            }
        }
    }

    // 销毁当前Bean所包含的bean
    Set<String> containedBeans;
    synchronized (this.containedBeanMap) {
        // Within full synchronization in order to guarantee a disconnected Set
        containedBeans = this.containedBeanMap.remove(beanName);
    }
    
    if (containedBeans != null) {
        // 如果包含其它bean,则递归删除
        // 这个地方白话解释一下:母猫死亡(发生了异常),母猫所包含的所以东西比如粑粑(Bean),都要回归大自然。
        for (String containedBeanName : containedBeans) {
            destroySingleton(containedBeanName);
        }
    }

    // 从其他bean的依赖项中移除被破坏的bean。这里是看一下dependentBeanMap中余下的value里是否含有当前beanName
    synchronized (this.dependentBeanMap) {
        for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
            Map.Entry<String, Set<String>> entry = it.next();
            Set<String> dependenciesToClean = entry.getValue();
            dependenciesToClean.remove(beanName);
            if (dependenciesToClean.isEmpty()) {
                it.remove();
            }
        }
    }

    // 删除bean准备好的依赖项信息。
    this.dependenciesForBeanMap.remove(beanName);
}

主要的销毁包含:

1. 销毁所有直接依赖此bean的bean(递归删除)

2. 如果存在的话,删除一次性注册的bean

3. 销毁此bean包含的所有bean(递归删除)

4. 遍历dependentBeanMap的value,看是否存在此bean

5. 删除自己已准备好的依赖项信息

这里涉及三个集合

/** 我拥有的人:key=我,value=我拥有的人 */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** 别人依赖我:key=我,value=依赖我的人 */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** 我依赖别人:key=我,value=我依赖的人 */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

图解一下

7. 创建多实例bean

// 原型模式
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);
}

protected void beforePrototypeCreation(String beanName) {
    // prototypesCurrentlyInCreation是一个本地线程变量,存储当前正在创建的多实例Bean
    Object curVal = this.prototypesCurrentlyInCreation.get();
    if (curVal == null) {
        // 如果当前线程没有创建任务,则设置为当前BeanName
        this.prototypesCurrentlyInCreation.set(beanName);
    }
    else if (curVal instanceof String) {
        // 如果当前存储的变量是String类型,则新建一个Set集合,存储这个String变量以及我们将要创建的beanName
        Set<String> beanNameSet = new HashSet<>(2);
        beanNameSet.add((String) curVal);
        beanNameSet.add(beanName);
        // 存储进线程本地变量
        this.prototypesCurrentlyInCreation.set(beanNameSet);
    }
    else {
        Set<String> beanNameSet = (Set<String>) curVal;
        // 转换成Set集合,然后把当前beanName添加进去
        beanNameSet.add(beanName);
    }
}
protected void afterPrototypeCreation(String beanName) {
    // 获取线程本地变量
    Object curVal = this.prototypesCurrentlyInCreation.get();
    // 如果是String类型,直接移除
    if (curVal instanceof String) {
        this.prototypesCurrentlyInCreation.remove();
    }
    else if (curVal instanceof Set) {
        // 如果是Set集合,先移除Set集合中的beanName
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.remove(beanName);
        // 如果集合为空,才去移除线程本地变量
        if (beanNameSet.isEmpty()) {
            this.prototypesCurrentlyInCreation.remove();
        }
    }
}

与单例模式不同的是创建前后有个处理的过程,看过程

1. 创建之前(目的是把任务[beanName]放进本地线程变量中)

  线程本地变量获取为空,则直接设置成当前beanName。

  获取到线程本地变量,并且类型为String,则新建一个Set集合,将新老变量添加到集合中,最后设置成线程本地变量。

  获取到线程本地变量,类型是Set集合,则先做类型转换,然后添加当前的beanName到集合中,最后设置成线程本地变量。

2. 创建Bean,在doCreateBean方法中有这么一行,如下:

  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));

  目的是用来检测循环依赖,添加到相应的缓存中,同时它是仅仅针对单例Bean。而多实例Bean的创建不会有这个过程的。

3. 创建之后(目的是把任务[beanName]从本地线程变量中移除)

  如果获取到的变量是String类型,证明只有这一个任务,直接执行remove即可。

  如果获取到的变量类型是Set集合类型,证明不止当前一个任务,要把当前任务从Set集合中删除;然后再判断Set集合是否为空,为空才会执行remove方法。

8. 在指定的scope(作用域)上实例化bean

这里呢,与前面两种不同的地方仅仅是多了个获取Scope的过程,其他部分都不是事。

-

☆ 扩展——IOC容器的关闭

不卖关子直接上,Java应用程序里可以添加关闭钩子。

public static void main(String[] args){
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        System.out.println("关闭之前我要优雅的处理资源");
    }));
}

这样,当以下情况会触发

1. 程序正常退出
2. 使用System.exit()
3. 终端Ctrl+C
4. 系统关闭
5. Kill pid命令干掉进程(不是kill -9 pid)

同样,在Spring里也是这样做的(org.springframework.context.support.AbstractApplicationContext#registerShutdownHook)

public void registerShutdownHook() {
    if (this.shutdownHook == null) {
        this.shutdownHook = new Thread("SpringContextShutdownHook") {
            public void run() {
                synchronized(AbstractApplicationContext.this.startupShutdownMonitor) {
                    AbstractApplicationContext.this.doClose();
                }
            }
        };
        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
}
/** @deprecated */
@Deprecated
public void destroy() {
    this.close();
}
public void close() {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.doClose();
        if (this.shutdownHook != null) {
            try {
                Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
            } catch (IllegalStateException var4) {
                ;
            }
        }
    }
}

当然Spring已经写好了,不用我们去管。但是我们遇到一些业务场景可能会用到,现有框架比如Dubbo,听说就是利用这个东西实现优雅停机的。

总结

实际上Spring的重点可以说有两部分

1. 容器(IOC)创建过程:

ApplicationContext app = new AnnotationConfigApplicationContext(Config.class);

2. Bean加载过程(也可以说是Bean的实例化过程):

app.getBean("user");

这两部分并不是井水不犯河水,因为容器创建过程,就涉及到单实例Bean的初始化过程了。

如果作用域是 Singleton,那么在容器创建的时候就会初始化,后面你getBean会直接返回缓存中的实例,生命周期交给容器处理。

如果作用域是 Prototype,那么每次调用getBean都会创建一个新的实例,生命周期交给调用者。

另外你还能发现,在Bean的实例化过程遇到的问题很多都是面试问的问题。比如:

BeanFactory和FactoryBean的区别?

Spring如何解决循环依赖的?

Bean的生命周期?等等

由于这部分内容比较多且复杂,一部分是年前写的,一部分是在老家写的,用的测试代码可能不一样,但是不影响Spring代码的思路。

原文地址:https://www.cnblogs.com/LUA123/p/12192197.html