zoukankan      html  css  js  c++  java
  • 基于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
Copyright © 2011-2022 走看看