美文网首页
细致地分析Spring Bean初始化的过程

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

作者: HannahLi_9f1c | 来源:发表于2021-02-20 15:39 被阅读0次

    看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<String> 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容器的初始化了。
    <T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                @Nullable Class<? extends Annotation>[] 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<String> 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<String> 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<Boolean>)
                                                ((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> T doGetBean(final String name, @Nullable final Class<T> 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<String> 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<Object>) () ->
    //从源码中我们可以看到其调用了 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<Constructor>() {
                                    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初始化的过程

          本文链接:https://www.haomeiwen.com/subject/hmnaxltx.html