spring bean的生命周期

328 阅读3分钟

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

对于java程序员来说,spring框架是面试中永远绕不开的话题,而在spring的一系列面试题中,spring bean的生命周期又是很多面试官非常喜欢问的。今天我们就来学习一下spring bean的生命周期。

先看下整体的流程图:

image.png

相信很多人在网上或多或少见过和这张类似的流程图,但这样看上去其实特别繁琐,不好记忆。

按我个人的理解,我觉得spring bean的生命周期可以分为四个阶段:

  1. bean的实例化(通过java反射方式生成对象)
  2. bean的属性赋值(PopulateBean()这个阶段其实会涉及到很多的问题,比如我们之前聊过的循环依赖问题和spring是怎样通过三级缓存的设计解决的,面试的时候都可以展开和面试官聊聊)
  3. bean的初始化(initializeBean)
  4. bean的销毁

上述流程除了第四部bean的销毁,其余逻辑几乎都在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法中体现:

看下源码

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
    if (instanceWrapper == null) {
    //实例化对象,里面第二次调用后置处理器
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    //属性填充,也就是我们常常说的自动注入
    //里面会完成第五次和第六次后置处理器的调用
    populateBean(beanName, mbd, instanceWrapper);
    //初始化spring
    //里面会进行第七次和第八次的后置处理器的调用
    exposedObject = initializeBean(beanName, exposedObject, mbd);
}

忽略了不相关的代码

图中在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 {
                //调用aware接口的相关方法
                invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
                //调用BeanPostProcessor的前置处理方法
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
                //调用InitMehod方法
                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()) {
                //调用BeanPostProcessor的后置处理方法 aop就是在此处实现的
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
}

通过源码我们可以很清晰的看到在bean完成真正的初始化之前都做了哪些工作

  1. 调用aware接口的相关方法 invokeAwareMethods(beanName, bean);(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)
private void invokeAwareMethods(final String beanName, final Object bean) {
		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);
			}
		}
	}
  1. 调用BeanPostProcessor的前置处理方法 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
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;
}
  1. 调用InitMehod方法: invokeInitMethods(beanName, wrappedBean, mbd);
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
                }
                if (System.getSecurityManager() != null) {
                        try {
                                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                //如果实现了InitializingBean接口,执行他的afterPropertiesSet方法
                                        ((InitializingBean) bean).afterPropertiesSet();
                                        return null;
                                }, getAccessControlContext());
                        }
                        catch (PrivilegedActionException pae) {
                                throw pae.getException();
                        }
                }
                else {
                        ((InitializingBean) bean).afterPropertiesSet();
                }
        }

        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);
            }
        }
    }
  1. 调用BeanPostProcessor的后置处理方法: applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@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;
}

这之后bean的初始化完成,就保存在spring应用的上下文当中,可以通过getBean的方式来调用,直到关闭,才会被销毁。

以上,感谢阅读。