如上图所示为Spring中Bean的一个完整生命周期,大体上可以分为实例化Instantiation、填充内部属性(属性赋值)Populate、初始化Initialization、销毁Destruction四个阶段。
实例化前准备阶段
从我的理解来说,它并不包含在bean的生命周期中,因为此时bean实例尚未创建,beanFactory中存储的仅是beanDefinition。通过实现BeanFactoryPostProcess接口的postProcessBeanFactory方法可以对beanDefinition进行修改,例如我们可以修改beanDefinition之间的依赖关系,例如aBeanDefinition.setDependsOn(bBeanDefinition),这样就表示在aBean创建前会先创建bBean,销毁bBean前会先销毁aBean。
但它是一个很重要的扩展点,可以通过实现接口来操作beanDefinition。
实例化、填充内部属性
- 即图中的第2、3步,在Spring源码中对应AbstractAutowireCapableBeanFactory.java的doCreateBean方法中的
createBeanInstance、populateBean方法。
在调用doCreateBean之前
会先进行一个resolveBeforeInstantiation操作,在这一步会给后置处理器一个机会返回代理对象,如果获取到了代理对象则直接返回不再进行后续创建过程,但是需要类是TargetSource类型,它是一个Aop框架接口一般不会用到它所以基本返回都是null。在这一步中会获取所有实现了InstantiationAwareBeanPostProcessor接口的类,调用它们的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)方法。我们经常说的AOP,利用的是代理模式,很核心的一点就是生成一个代理对象,相关类为AbstractAutoProxyCreator,它实现了SmartInstantiationAwareBeanPostProcessor接口,它也是在这一步根据类有没有实现接口采用JDK或CGLIB的形式来获取代理对象。
且SmartInstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口并包含getEarlyBeanReference方法,其实大部分代理对象的创建是通过AbstractAutoProxyCreator的postProcessAfterInitialization()或getEarlyBeanReference方法创建的。
之后在populateBean方法中会先调用InstantiationAwarePostProcessor的postProcessAfterInstantiation
在调用InstantiationAwarePostProcessor的postProcessPropertyValues(对将要填充的属性进行处理)
之后再进行属性填充
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean. 执行构造方法实例化bean -> 2
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
....
// Initialize the bean instance.
Object exposedObject = bean;
try {
//填充内部属性 -> 3
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 初始化 -> 4-8
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
.....
// Register bean as disposable. 注册销毁回调函数
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
}
初始化阶段
在上面代码块中对应initializeBean中的部分,这一块包含了图中的第4到8步且为我们提供了众多扩展点,进入方法展开说一下
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
//检查有没有实现aware相关接口 -> 4
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//执行BeanPostProcessor.postProcessBeforeInitialization方法 -> 5
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 判断bean有没有实现InitializingBean接口,如果有实现则执行afterPropertiesSet()方法 ->6
// 如果bean有定义自己的init-method方法则执行 ->7
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.postProcessAfterInitialization(wrappedBean, beanname) -> 8
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
- 图中第4步,在invokeAwareMethods方法中会检查bean有没有实现BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口,如果实现了,则会调用相关方法将对应Spring容器资源赋值方法。
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) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
-
在第5步,很简单就是找出所有实现了BeanPostProcessor接口的实现类,执行它们的postProcessBeforeInitialization(WrappedBean, beanName)方法。在上面第4步检查Aware接口设置相关属性,都是与SpringFactory相关的,其实ApplicationContext也会有自己的Aware,就是在这一步进行检查并设置的。相关的类名为ApplicationContextAwareProcessor,它会检查bean有没有实现EnvironmentAware、ApplicationContextAware等接口,将相关属性进行赋值操作
-
在invokeInitMethods方法中包含了第6-7步,代码如下
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
....
// -> 6
((InitializingBean) bean).afterPropertiesSet();
...
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// ->7
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
首先是判断bean有没有实现InitializingBean接口如果实现了,则执行afterPropertiesSet()方法,需要注意的是该方法是针对单个bean的,而BeanPostProcess应用于所有的bean;该方法并没用参数,一般是进行一些属性的校验或修改。
之后会检查是否有initMethod方法,如果指定了则执行该方法。java中指定初始化方法有两种方式,一种是使用xml配置bean的方式<bean id=“myBean” class=“xxxx.MyBean” init-method=“init” destroy-method="destroy”>,另外一种是使用注解的方式@Bean(initMethod =“init” ,destroyMethod =“destroy” )。大家常说的@PostConstruct严格来说并不能算是一种initMethod,它的实现还是利用了BeanPostProcess,在CommonAnnotationBeanPostProcessor类中将所有被@PostContruct和@PreDestroy注解标注的方法识别出来,被@PostContruct方法标注的方法放在InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization中执行。
-
在第8步则是执行所有BeanPostProcessor实现类的的postProcessAfterInitialization方法
-
第9步需要注册bean销毁时的回调函数
首先会判断该bean是否需要注册销毁回调函数,具体判断逻辑在registerDisposableBeanIfNecessary(beanName, bean, mbd)中的requiresDestruction(Object bean, RootBeanDefinition mbd)方法
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean != null &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
//DisposableBeanAdapter
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
if (bean instanceof DisposableBean || closeableInterface.isInstance(bean)) {
return true;
}
String destroyMethodName = beanDefinition.getDestroyMethodName();
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
}
return StringUtils.hasLength(destroyMethodName);
}
public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
if (!CollectionUtils.isEmpty(postProcessors)) {
for (BeanPostProcessor processor : postProcessors) {
if (processor instanceof DestructionAwareBeanPostProcessor) {
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
try {
if (dabpp.requiresDestruction(bean)) {
return true;
}
}
catch (AbstractMethodError err) {
// A pre-4.3 third-party DestructionAwareBeanPostProcessor...
// As of 5.0, we can let requiresDestruction be a Java 8 default method which returns true.
return true;
}
}
}
}
return false;
}
如果bean包含有destroyMethod方法(包括在xml中、@Bean中指明destroyMethod),或者实现了DisposableBean接口,或者当前实现了DestructionAwareBeanPostProcessor
接口的实现类适用于该bean,则根据该bean的创建DisposableBeanAdapter对象,获取所有适用该bean的DestructionAwareBeanPostProcessor对象,并将disposableBeanAdapter对象存储进disposableBeans Map中。此时销毁时的回调函数注册完毕
bean销毁
经历过上述阶段之后,bean已经创建成功了,正常运行之后,在进行销毁时,会调用注册的回调函数。从disposableBeans map中获取对应的disposableBeanAdapter对象,DisposableBeanAdapter也实现了DisposableBean接口重写了的destroy方法。在其中首先会判断如果有DestructionAwareBeanPostProcessor适用于该bean,会调用其postProcessBeforeDestruction方法;其次如果该bean本身就实现了DisposableBean接口,也会调用destroy方法;最后执行该bean自定义的的distroyMethod方法,之后进行销毁。