• spring生命周期源码查看并且解析


    网上一大堆只给我出一个spring的周期流程图,我觉得这并不是个人理解,如果加入个人理解,并且配上源代码,那么会更好的理解。不多说,下面直接上干货。

    先给出自己理解的spring流程:

    1、实例化bean

    2、设置对象属性

    3、初始化

    4、使用和销

    1. 实例化:第 1 步,实例化一个 bean 对象;
    2. 属性赋值:第 2 步,为 bean 设置相关属性和依赖;
    3. 初始化:第 3~7 步,步骤较多,其中第 5、6 步为初始化操作,第 3、4 步为在初始化前执行,第 7 步在初始化后执行,该阶段结束,才能被用户使用;
    4. 销毁:第 8~10步,第8步不是真正意义上的销毁(还没使用呢),而是先在使用前注册了销毁的相关调用接口,为了后面第9、10步真正销毁 bean 时再执行相应的方法。

    下面我们来结合源代码理解:

     1、doCreateBean方法如下:

    // AbstractAutowireCapableBeanFactory.java
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {
     
        // 1. beanWrapper是实例化bean的第一步
        BeanWrapper instanceWrapper = null;
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        
        Object exposedObject = bean;
        try {
            // 2. populateBean方法进行属性赋值
            populateBean(beanName, mbd, instanceWrapper);
            // 3. 调用initilizeBean进行spring初始化(下面有详细的代码步骤了解初始化步骤)
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
     
        // 4. 销毁-注册回调接口
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
     
        return exposedObject;
    }

    上面的代码我们给了注释,每一步骤对应我们自己总结的1、2、3、4的spring生命周期阶段,下面我在再详细看看 initializeBean 的初始化阶段源代码

    // AbstractAutowireCapableBeanFactory.java
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // 3. 检查 Aware 相关接口并设置相关依赖
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
     
        // 4. BeanPostProcessor 前置处理
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
     
        // 5. 若实现 InitializingBean 接口,调用 afterPropertiesSet() 方法
        // 6. 若配置自定义的 init-method方法,则执行
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
        }
        // 7. BeanPostProceesor 后置处理
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
     
        return wrappedBean;
    }



    在 invokInitMethods() 方法中会检查 InitializingBean 接口和 init-method 方法,销毁的过程也与其类似:


    // DisposableBeanAdapter.java
    public void destroy() {
        // 9. 若实现 DisposableBean 接口,则执行 destory()方法
        if (this.invokeDisposableBean) {
            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((DisposableBean) this.bean).destroy();
                        return null;
                    }, this.acc);
                }
                else {
                    ((DisposableBean) this.bean).destroy();
                }
            }
        }
        
        // 10. 若配置自定义的 detory-method 方法,则执行
        if (this.destroyMethod != null) {
            invokeCustomDestroyMethod(this.destroyMethod);
        }
        else if (this.destroyMethodName != null) {
            Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
            if (methodToInvoke != null) {
                invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
            }
        }
  • 相关阅读:
    【LeetCode】13. Roman to Integer (2 solutions)
    【LeetCode】16. 3Sum Closest
    【LeetCode】18. 4Sum (2 solutions)
    【LeetCode】168. Excel Sheet Column Title
    如何应用性能测试常用计算公式
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    Monkey测试3——Monkey测试结果分析
    Monkey测试2——Monkey测试策略
    Monkey测试1——Monkey的使用
    TestNG 三 测试方法
  • 原文地址:https://www.cnblogs.com/qq1141100952com/p/15057423.html
Copyright © 2020-2023  润新知