细致地分析Spring Bean初始化的过程

看Spring源码要带有目的地学习,不然很容易被其复杂的继承体系绕的找不着北。因此这篇文章从大处着手,先是大体理出整个Spring启动的脉络,来分析Spring 的Ioc和DI是如何实现的,然后再从细节分析Spring Ioc一些常见的问题。对于阅读源码来说,最重要的是学习其中的设计思路、编程思想,但是最初级地学习是要先弄清它的实现。对于博主来说水平有限,只能谈谈自己的理解。(为了简化理解,本文省略了一些源码,关注核心部分)

一、整体来看Spring的启动过程。

1. refresh->开始刷新容器

我们从容器初始化入口类的refresh方法开始,这个方法由父类AbstractApplicationContext 定义实现,使用SpringBoot方式启动也会进入到该方法初始化Spring容器以及Bean。这个方法里调用obtainFreshBeanFactory和finishBeanFactoryInitialization这两个关键方法。

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
                        ........
            try {
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }
              .........
        }
    }

2. obtainFreshBeanFactory->准备容器,解析Bean

这个方法调用子类的refreshBeanFactory。主要是创建出Bean的容器,也就是BeanFactory,本质上就是一个Map,存放BeanDefinition,然后就使用xml或者注解的方式解析出BeanDefinition,然后将这些Bean注册到容器中,到这一步对于Bean的前置工作就做好了。返回BeanFactory后下一步当然就是对于容器的Bean进行初始化了。这里的refreshBeanFactory还是基于模板方法,在父类定义出该方法,具体怎么刷新容器交由子类AbstractRefreshableApplicationContext

    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
                    //当前已经有Bean容器,就先将其Bean销毁,然后关闭容器
            destroyBeans();
            closeBeanFactory();
        }
        try {
                      //创建容器
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            customizeBeanFactory(beanFactory);
                       //加载Bean 定义
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        }
        catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

3. loadBeanDefinitions->Bean载入容器

具体就是解析出BeanDefinition,由于层次太深,这里先不往下走。

4. finishBeanFactoryInitialization->非懒加载单例Bean的初始化

refresh方法中更关键的方法就是finishBeanFactoryInitialization,在这个方法中调用beanFactory.preInstantiateSingletons()进行非懒加载单例Bean的初始化,而多例则是在getBean的时候创建,这里的初始化交由DefaultListableBeanFactory子类进行

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        .......

        // Instantiate all remaining (non-lazy-init) singletons.
        beanFactory.preInstantiateSingletons();
    }

5. preInstantiateSingletons

这个方法中真正调用了getBean方法,稍后会认真分析这里,是怎么对Bean进行初始化的。相关的调用链getBean->doGetBean->createBean->doCreateBean

@Override
    public void preInstantiateSingletons() throws BeansException {
    ......
        List beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                            .........
                    getBean(beanName);
            
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        
    }
6. doCreateBean->实例化、属性注入、初始化

终于走到了doCreateBean,可以开始对具体的Bean进行初始化了。这里的核心方法就是createBeanInstance(反射获取对象的实例)、populateBean属性注入、initializeBean初始化。下面还是要细致地分析这个方法

二、分析Spring的一些细节

1. loadBeanDefinitions如何将Bean载入容器

loadBeanDefinitions可以由不太子类来实现,一种方式是载入xml文件,然后解析dom树来解析获取BeanDefinition,由于目前主流是使用注解来定义Bean的,所以这篇文章还是基于注解加载BeanDefinition。

  • 从loadBeanDefinitions进入到register,register方法遍历class文件,registerBean注册Bean
@Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
         ...........
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            for (String configLocation : configLocations) {
                try {
                    Class clazz = ClassUtils.forName(configLocation, getClassLoader());
                    if (logger.isTraceEnabled()) {
                        logger.trace("Registering [" + configLocation + "]");
                    }
                    reader.register(clazz);
                }
                
            }
        }
    }
  • doRegisterBean解析beanClass文件,生成基于注解的Bean,最后调用registerBeanDefinition注册Bean。到这一步终于完成Bean容器的初始化了。
 void doRegisterBean(Class beanClass, @Nullable Supplier instanceSupplier, @Nullable String name,
            @Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }

        abd.setInstanceSupplier(instanceSupplier);
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
        abd.setScope(scopeMetadata.getScopeName());
        String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
       //解析注解,设置Bean的lazy、primary等属性
        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        ......
        for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
            customizer.customize(abd);
        }

        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
    }
  • registerBeanDefinition将Bean注入到map容器,这里有一些细节可以关注一下
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
             ......
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            //这里省略了如果已存在bean,是否允许覆盖的判断,以及一些debug日志
               this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {
                //如果Bean已经开始创建了,
            if (hasBeanCreationStarted()) {
                // Cannot modify startup-time collection elements anymore (for stable iteration)
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
//其实博主不是很理解这里为什么要这样new出新的 updatedDefinitions ,然后再赋值。。。
                    List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    removeManualSingletonName(beanName);
                }
            }
            else {
                // Still in startup registration phase
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                removeManualSingletonName(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition != null || containsSingleton(beanName)) {
            resetBeanDefinition(beanName);
        }
    }

2. 初始化Bean

  • 首先是对所有非懒加载并且单例的Bean初始化,然后对于实现了SmartInitializingSingleton的类进行回调。
@Override
    public void preInstantiateSingletons() throws BeansException {
        ........
        List beanNames = new ArrayList<>(this.beanDefinitionNames);

        // 遍历所有bean,对于单例非懒加载的Bean初始化
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                   //如果是实现了FactoryBean,有一些特殊处理
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean factory = (FactoryBean) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction)
                                            ((SmartFactoryBean) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
//省略了对于实现了SmartInitializingSingleton方法的回调。如果想要在Bean初始化之后执行一些操作,可以实现这个接口SmartInitializingSingleton。
    }

  • getBean()->doGetBean,在doGetBean里面代码就很长了,先尝试从缓存中取Bean对象,(这里面还用了三层缓存解决循环依赖问题,那为什么要使用三层,两层或者一层不可以吗?)如果缓存中获取不到,那么就要判断是单例还是多例还是其他,具体看注释。
    protected  T doGetBean(final String name, @Nullable final Class requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
                //获取唯一的beanName
        final String beanName = transformedBeanName(name);
        Object bean;
        // 尝试从缓存中获取
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
         //····省略了log
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // // 如果当前容器中没有指定的 bean,且当前容器的父容器不为空
            // 则从父容器中去找,如果父容器也没有,则沿着当前容器的继承体系一直向上查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                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 {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
 // 获取当前 bean 所依赖bean 的 beanName,下面的 getBean(dependsOnBean) 方法会触发
                // getBean() 的递归调用,直到取到一个不依赖任何其它 bean 的 bean 为止。
                // 比如:beanA 依赖了 beanB,而 beanB 依赖了 beanC,那么在实例化 beanA 时会先实例化
                // beanC,然后实例化 beanB 并将 beanC 注入进去,最后实例化 beanA 时将 beanB 注入
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // 创建单例,这里使用了匿名表达式
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
        
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                                  //多例Bean的创建
                else if (mbd.isPrototype()) {
                         // 原型模式 (Prototype) 每次都会创建一个新的对象
                    Object prototypeInstance = null;
                    try {
                                          // Spring的扩展点,回调方法
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                                               //回调方法
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
// 要创建的 bean 既不是单例模式,也不是原型模式,则根据该 bean元素 在配置文件中
                // 配置的生命周期范围,选择实例化 bean 的合适方法,这种在 Web 应用程序中
                // 比较常用,如:request、session、application 等的生命周期
                else {
                    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;
            }
        }

        // 省略了对Bean的校验工作。。
    
        return (T) bean;
    }
  • createBean->doCreateBean开始实例化Bean了。这里的代码十分长,但是我们只要抓住核心,就不会找不到重点。。。
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
 // 如果这个 bean 是单例的,则从缓存中获取这个 beanName 对应的 BeanWrapper实例,并清除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
//!!!!重点关注的地方,实例化对象!!!!
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 省略了Spring的一些调用点。。
        //earlySingletonExposure 表示单例允许循环依赖,beanName正在创建。
        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");
            }
 // 这里是一个 ObjectFactory 的匿名内部类,为了防止循环引用,尽早持有对象的引用
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
//!!!!这里也是重点,依赖注入就是在这里完成的
            populateBean(beanName, mbd, instanceWrapper);
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
 // 如果根据名称获取的已注册的 bean 和正在实例化的 bean 是同一个
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
 // 如果当前 bean 依赖其他 bean,并且当发生循环引用时不允许新创建实例对象
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                
                }
            }
        }

        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }
  • 继续往下看createBeanInstance创建实例对象,使用策略模式实例化getInstantiationStrategy().instantiate
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //.....其他的特殊处理
        // 没有特殊处理的话,就默认使用无参构造器进行初始化
        return instantiateBean(beanName, mbd);
    }

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged((PrivilegedAction) () ->
//从源码中我们可以看到其调用了 SimpleInstantiationStrategy 实现类来生成 bean 
//对象,这个类是 Spring 用来生成 bean 对象 的默认类,它提供了两种策略来实例化 
//bean 对象,一种是利用 Java 的反射机制,另一种是直接使用 CGLIB。
                        getInstantiationStrategy().instantiate(mbd, beanName, parent),
                        getAccessControlContext());
            }
            else {
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }

  • 如果 配置的bean 中没有方法覆盖,则使用 Java 的反射机制实例化对象,否则使用 CGLIB
public class SimpleInstantiationStrategy implements InstantiationStrategy {

    // 使用初始化策略实例化 bean对象
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
        // 如果 配置的bean 中没有方法覆盖,则使用 Java 的反射机制实例化对象,否则使用 CGLIB
        if (beanDefinition.getMethodOverrides().isEmpty()) {
            Constructor constructorToUse;
            synchronized (beanDefinition.constructorArgumentLock) {
                // 获取对象的构造方法对 bean 进行实例化
                constructorToUse = (Constructor) beanDefinition.resolvedConstructorOrFactoryMethod;
                // 如果前面没有获取到构造方法,则通过反射获取
                if (constructorToUse == null) {
                    // 使用 JDK 的反射机制,判断要实例化的 bean 是否是接口
                    final Class clazz = beanDefinition.getBeanClass();
                    // 如果 clazz 是一个接口,直接抛出异常
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            // 这里使用了一个 PrivilegedExceptionAction 的匿名内部类,使用反射机制获取 bean 的构造方法
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                                public Constructor run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                        }
                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            // 根据传入的 Constructor,在 BeanUtils 中调用该 Constructor 的
            // newInstance(Object...) 方法,实例化指定对象
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            /**
             * !!!!!!!!!!!!!!
             * 使用 CGLIB 来实例化对象
             * 调用了 CglibSubclassingInstantiationStrategy 中的实现
             * !!!!!!!!!!!!!!
             */
            return instantiateWithMethodInjection(beanDefinition, beanName, owner);
        }
    }
}
  • 使用CGLIB实例化的过程
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {

    /**
     * 下面两个方法都通过实例化自己的私有静态内部类 CglibSubclassCreator,
     * 然后调用该内部类对象的实例化方法 instantiate() 完成实例化
     */
    protected Object instantiateWithMethodInjection(
            RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {

        return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);
    }

    @Override
    protected Object instantiateWithMethodInjection(
            RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
            Constructor ctor, Object[] args) {

        return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
    }

    /**
     * 为避免 3.2 之前的 Spring 版本中的外部 cglib 依赖而创建的内部类。
     */
    private static class CglibSubclassCreator {

        private static final Log logger = LogFactory.getLog(CglibSubclassCreator.class);

        private final RootBeanDefinition beanDefinition;

        private final BeanFactory owner;

        public CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
            this.beanDefinition = beanDefinition;
            this.owner = owner;
        }

        // 使用 CGLIB 进行 bean对象 实例化
        public Object instantiate(Constructor ctor, Object[] args) {
            // 实例化 Enhancer对象,并为 Enhancer对象 设置父类,生成 Java 对象的参数,比如:基类、回调方法等
            Enhancer enhancer = new Enhancer();
            // 将 bean 本身作为其父类
            enhancer.setSuperclass(this.beanDefinition.getBeanClass());
            enhancer.setCallbackFilter(new CallbackFilterImpl());
            enhancer.setCallbacks(new Callback[] {
                    NoOp.INSTANCE,
                    new LookupOverrideMethodInterceptor(),
                    new ReplaceOverrideMethodInterceptor()
            });

            // 使用 CGLIB 的 create() 方法生成实例对象
            return (ctor == null) ? enhancer.create() : enhancer.create(ctor.getParameterTypes(), args);
        }
    }
}
  • 实例化完之后,就该进行属性注入了,属性注入的方式包括@Autowird,@Resource等
 /**
     * 为属性赋值,完成依赖注入
     */
    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        // 获取 RootBeanDefinition 中设置的 属性值PropertyValues,这些属性值来自对
        // bean元素 的解析
        PropertyValues pvs = mbd.getPropertyValues();
        // 省略检查BeanWrapper和在设置属性之前调用 bean 的 PostProcessor 后置处理器
    
        // 依赖注入开始,首先处理 autowire 自动装配的注入
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // 对 autowire 自动装配的处理,根据 bean 名称自动装配注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // 根据 bean 类型自动装配注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        // 省略检查容器是否持有用于处理单例模式 bean 关闭时的后置处理器
        /**
         * !!!!!!!!!!!
         * 对属性进行依赖注入
         * !!!!!!!!!!!
         */
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

本文Bean初始化部分未完待更,目前先写到属性注入这里吧。。

三、一些常见问题

1. 讲讲Spring,Bean生命周期,bean创建过程

Spring启动过程简要来说就是创建容器,解析Bean封装成BeanDefinition,将Bedefinition注册到容器中,然后遍历容器,对容器中非单例懒加载的Bean初始化,初始化过程先是初始化依赖的Bean,然后递归进行初始化,每次先尝试从三级缓存中取Bean,然后再初始化,保证了Bean的唯一性。对于Bean的生命周期来说,主要包含实例化、属性注入、初始化、销毁四个生命周期。

2. 循环依赖如何解决,为什么三层依赖,两层可以吗?

Spring能够解决的是setter注入方式,不能解决构造器注入的循环依赖。使用的是Java的引用传递和三级缓存解决的,第一级缓存是Bean实例的缓存singletonObjects,第二层是提前暴露出来的缓存earlySingletonObjects,第三层是Bean工厂的缓存singletonFactory。取缓存的逻辑如下所示:Spring首先从singletonObjects(一级缓存)中尝试获取,如果获取不到并且对象在创建中,则尝试从earlySingletonObjects(二级缓存)中获取,如果还是获取不到并且允许从singletonFactories通过getObject获取,则通过singletonFactory.getObject()(三级缓存)获取。如果获取到了则移除对应的singletonFactory,将singletonObject放入到earlySingletonObjects,其实就是将三级缓存提升到二级缓存中!

 protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject;
    }

那么工厂缓存是什么时候设置的呢?我们通过查看createBean的源码可以发现是在实例化之后。这段代码发生在createBeanInstance之后,也就是说单例对象此时已经被创建出来的。这个对象已经被生产出来了,虽然还不完美(还没有进行初始化的第二步和第三步),但是已经能被人认出来了(根据对象引用能定位到堆中的对象),所以Spring此时将这个对象提前曝光出来让大家认识,让大家使用

   if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
.....
        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
        //设置三级缓存
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

那么为什么不用二级缓存呢?为了解决代理对象的循环依赖才使用三级缓存
https://www.cnblogs.com/semi-sub/p/13548479.html

3. Spring注入方式

构造方法注入,setter注入,基于注解的注入

你可能感兴趣的:(细致地分析Spring Bean初始化的过程)