Spring启动流程

2021-12-18  本文已影响0人  Corey1874

一、源码

核心方法reflesh()

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 准备工作,初始化Spring状态,并确认配置正确
            prepareRefresh();

            // 获取bean工厂
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 初始化,给各属性设置默认值
            prepareBeanFactory(beanFactory);

            try {
                // 空方法,用于扩展。可以对初始化之后的bean工厂做修改
                postProcessBeanFactory(beanFactory);

                // 实例化并调用所有注册的BeanFactoryPostProcessor Bean。
                // BeanFactoryPostProcessor是对Spring对外暴露的接口,可以进行自定义扩展。
                // 它可以在容器实例化bean之前读取bean的定义信息,并修改它
                invokeBeanFactoryPostProcessors(beanFactory);

                // 注册BeanPostProcessor
                // 注意这里只是注册,真正调用是在bean实例化之后,初始化之前
                registerBeanPostProcessors(beanFactory);

                // 国际化相关处理
                initMessageSource();

                // 初始化事件发布广播器
                initApplicationEventMulticaster();

                // 初始化特殊bean 方法为空,留待扩展
                onRefresh();

                // 注册监听器
                registerListeners();

                // 核心方法: 实例化所有非懒加载的单例对象
                finishBeanFactoryInitialization(beanFactory);

                // 事件发布
                finishRefresh();
            }
            catch (BeansException ex) {
                ...
                ...
                destroyBeans();
                cancelRefresh(ex);
                ...
            }
            finally {
                resetCommonCaches();
            }
        }
    }

obtainFreshBeanFactory()

该方法获取工厂,将bean定义信息注册到beanFactory中。

    protected final void refreshBeanFactory() throws BeansException {
        // 如果已有工厂,则销毁bean关闭旧工厂
        if (hasBeanFactory()) {
            destroyBeans();
            closeBeanFactory();
        }
        try {
            // 创建工厂 DefaultListableBeanFactory 此为管理bean的核心对象
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 1、设置是否允许覆盖同名称不同定义的bean 同一配置文件中bean重复会报错,不同文件则覆盖
            // 2、设置是否允许循环依赖。默认允许属性的循环依赖,但是如果构造方法发生循环依赖,Spring无法解决
            customizeBeanFactory(beanFactory);
            // 加载bean的定义信息(XML文件读取及解析,默认命名空间的解析,自定义标签的解析)
            loadBeanDefinitions(beanFactory);
            ...
        }
        ...

finishBeanFactoryInitialization(beanFactory)

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        ...
        ...
        ...
        // 这里做了1、初始化类型转换器 2、注册LoadTimeWeaverAware 的转换器 
        // 3、禁止使用临时类加载器进行类型匹配 4、允许缓存bean定义信息 不重要故省略
        ...
        ...
        ...
        
        // 预实例化
        beanFactory.preInstantiateSingletons();
    }

preInstantiateSingletons()

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

        // 遍历对象名称列表,开始实例化(非懒加载对象)
        for (String beanName : beanNames) {
            // 合并bean定义信息,因为bean定义可能被修改,所以合并之后可以获取最新的定义 
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 对象需满足:非抽象、非懒加载、单例
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 是否是FactoryBean
                if (isFactoryBean(beanName)) {
                    // 处理FactoryBean
                    // 加上“&”前缀 获取xxxFactoryBean实例
                    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 {
                    // 处理普通bean
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

isFactoryBean()

这个方法作用是根据bean名称判断是否是FactoryBean类型

注:
Spring中存在两类bean,一种是普通bean,可以直接通过xml配置中的class属性利用发射进行实例化,而另一种bean创建逻辑比较复杂,不方便利用配置创建,故可以采用实现FactoryBean< T >接口定制实例化bean的逻辑。我们根据id"xxxFactoryBean"获取到的xxxFactoryBean对象不是对应类的实例(即不是xxxFactoryBean本身),而是它getObject()方法返回的对象,并且返回对象是否是单例,由其中方法isSingleton()来决定。如果要获xxxFactoryBean它本身,需要在id前加上"&".
举例:我们熟悉的有SqlSessionFactoryBean

getBean()

getBean是创建bean的核心方法

    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

doGetBean()

源码中,以do开头命名的方法,意味着是真正处理核心逻辑的方法,即真正干事的方法

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

        // 规范名称:1、FactoryBean需去掉"&" 2、别名
        final String beanName = transformedBeanName(name);
        Object bean;

        // 尝试从缓存中获取单例
        // bean 并不是在创建中状态 所以只会取到一级缓存为止,一级缓存没有不会往二级三级查找
        // getSingleton()方法为Spring解决循环依赖的核心
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            ...
            // 返回实例
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        // 缓存中获取不到 才创建
        else {
            if (isPrototypeCurrentlyInCreation(beanName)) {
                // 原型模式不支持解决循环依赖
                throw new BeanCurrentlyInCreationException(beanName);
            }
            // 如果有父容器 且bean在父容器有定义 则通过父容器获取
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                ...
            }

            // 如果不单纯是检查类型 标记bean为已创建
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                // 合并bean定义信息 检查是否抽象
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 确保bean依赖的对象先完成初始化    
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    // 递归?
                    ...
                }

                if (mbd.isSingleton()) {
                    // 单例
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // 开始创建 核心方法
                            return createBean(beanName, mbd, args);
                        }
                        // 创建失败 删除缓存
                        ...
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 其他如原型模式等 省略
                ...
            }
            // 创建失败 会清理缓存
            ...
        }

        // 根据requiredType  转换bean类型
        ...
        return (T) bean;
    }

createBean()

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
        ...
        try {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            ...
            return beanInstance;
        }
        ...
    }

doCreateBean()

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
        // ********************实例化********************
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            // 尝试从缓存获取
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 通过构造方法创建bean实例
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        ...

        // 后置处理器修改bean定义信息
        ...

        // 处理缓存 解决循环引用
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            ...
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // ********************初始化********************
        Object exposedObject = bean;
        try {
            // 根据配置文件value值 填充属性
            populateBean(beanName, mbd, instanceWrapper);
            // 初始化方法
            // 前置-initmethod - 后置
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            ...
        }

        // 循环依赖检查 看是否需要抛异常
        if (earlySingletonExposure) {
            ...
        }

        try {
            // 注册DisposableBean,如果配置了destroy-methoy,这里需要注册以便于在销毁的时候调用
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            ...
        }
        return exposedObject;
    }

createBeanInstance()

    /**
     * 从三种策略中选择一种来实例化:1、工厂方法 2、构造函数自动装配 3、简单实例化
     */
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 解析并确保class有效(不为空、修饰符为public)
        
        ...
        
        // 配置特殊的回调,通过回调创建bean
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        // 通过工厂方法创建bean
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // 解析过的构造器/工厂方法会缓存,以便创建相同的bean
        boolean resolved = false;
        boolean autowireNecessary = false;
        // 构造函数参数为空
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                // 判断缓存中是否有已解析的构造函数 进行标记
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        // 如果已经解析过 使用已经解析好的构造函数
        if (resolved) {
            ...
        }
        // 由后置处理器决定返回哪些构造方法
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            // 构造函数自动注入
            return autowireConstructor(beanName, mbd, ctors, args);
        }
        
        ...

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

instantiateBean()

    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        ... 
        // 这里只关注instantiate()方法 
        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        
        ...
    }

instantiate()

    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        ...
        // 只关注instantiateClass()方法
        return BeanUtils.instantiateClass(constructorToUse);
        ...
    }

instantiateClass()

    public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
        Assert.notNull(ctor, "Constructor must not be null");
        try {
            ...
            else {
                Class<?>[] parameterTypes = ctor.getParameterTypes();
                ...
                Object[] argsWithDefaultValues = new Object[args.length];
                for (int i = 0 ; i < args.length; i++) {
                    ...
                }
                //*******************这里通过newInstance最终创建了实例******************************
                return ctor.newInstance(argsWithDefaultValues);
            }
        }
        ...
    }

使用构造函数实例化对象 (反射的方法实例化对象)。至此,实例化完成,一直往上返回实例,直到回到createBean(),开始进行初始化

initializeBean()

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // Spring Aware自动装配
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                // invokeAwareMethods内部逻辑:
                // 1、判断是否实现了Aware接口
                // 2、判断具体实现了那个Aware接口(Aware、BeanClassLoaderAware、BeanFactoryAware)
                // 3、直接调用XxxAware接口的特有方法实现XxxAware的自动装配
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
        // 除了上述三个Aware 剩余Aware在 ApplicationContextAwareProcessor中实现 这里不细说
        

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // before-后置处理器
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 初始化方法:initMethod
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        ...
        
        if (mbd == null || !mbd.isSynthetic()) {
            // after-后置处理器
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

至此实例化、初始化完成!

二、总结

总的来说,bean的创建流程主要如下:
1、创建bean工厂,加载bean定义信息BeanDefination (obtainFreshBeanFactory())
2、实例化 (createBeanInstance())
3、填充属性 (populateBean())
4、初始化前置处理 (applyBeanPostProcessorsBeforeInitialization())
5、初始化 (invokeInitMethods())
7、初始化后置处理 (applyBeanPostProcessorsAfterInitialization())

上一篇 下一篇

猜你喜欢

热点阅读