bean是由Spring IoC容器托管的对象,其生命周期完全由容器控制,不需要垃圾回收。
以下是ioc托管下的bean的生命周期。
- 实例化bean对象:容器调用createBean进行实例化,相当于程序中的new xx();
- 设置对象属性(将值和Bean的引用注入进Bean对应的属性中,即依赖注入)
- 注入Aware接口
1)检查是否实现了BeanNameAware接口:如果实现了的话就调用setBeanName(String beanId)方法(此处传递的是Spring配置文件中Bean的ID)
2)检查是否实现了BeanFactoryAware接口:如果实现了的话就调用setBeanDFactory (BeanFactory beanFactory)方法,获取Spring容器
3)检查是否实现了ApplicationContextAwaer接口,如果实现了的话就调用setApplicationContext(ApplicationContext applicationContext)方法,获取Spring容器
BeanFactory作用与ApplicationContext类似,都是为了获取Spring容器
不同的是Spring容器在调用setApplicationContext方法时传入Spring上下文,而Spring容器在调用setBeanDactory时传递的是Spring工厂本身
附注:
ApplicationContext是BeanFactory的子接口
当经过上述几个步骤后,bean对象已经被正确构造
-
检查是否实现BeanPostProcessor接口(如果想要对象被使用前再进行一些自定义的处理,则实现此接口)。
1)postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行,因此称为前置处理。 所有Aware接口的注入就是在这一步完成的。
//前置处理后进入5.InitializingBean与init-method阶段
2)postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行,因此称为后置处理。 -
InitializingBean与init-method
InitializingBean接口只有一个函数:afterPropertiesSet(),其作用与在配置文件中对Bean使用init-method声明初始化的作用一样,都是在Bean的全部属性设置成功后执行的初始化方法。
这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。
Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名,Spring便会在初始化阶段执行我们设置的函数。
附注:
init-method本质上仍然使用了InitializingBean接口。
以上工作完成以后就可以用这个Bean了
- Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁
- 销毁bean
1)如果实现了DisposableBean接口,会调用其实现的destroy方法
2)如果在Bean定义文件中配置了destroy-method属性,会自动调用其配置的销毁方法
----------------------------bean的生命周期结束----------------------------
用于辅助理解的流程图: