一、bean的生命周期
1.1 代码示例
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("execute BeanFactoryPostProcessor#postProcessBeanFactory");
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("execute BeanPostProcessor#postProcessBeforeInitialization for:"+beanName);
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("execute BeanPostProcessor#postProcessAfterInitialization for:"+beanName);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
System.out.println(
"execute InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation for:"
+ beanName);
return InstantiationAwareBeanPostProcessor.super
.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName)
throws BeansException {
System.out.println(
"execute InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation for:"
+ beanName);
return InstantiationAwareBeanPostProcessor.super
.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
System.out.println("execute InstantiationAwareBeanPostProcessor#postProcessProperties for:"
+ beanName);
return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
}
}
public class User implements BeanFactoryAware, BeanNameAware, ApplicationContextAware,
InitializingBean, DisposableBean {
/**
* user's name.
*/
private String name;
/**
* user's age.
*/
private int age;
/**
* bean factory.
*/
private BeanFactory beanFactory;
/**
* application context.
*/
private ApplicationContext applicationContext;
/**
* bean name.
*/
private String beanName;
public User() {
System.out.println("execute User#new User()");
}
public void setName(String name) {
System.out.println("execute User#setName——" + name);
this.name = name;
}
public void setAge(int age) {
System.out.println("execute User#setAge——" + age);
this.age = age;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("execute BeanFactoryAware#setBeanFactory");
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String s) {
System.out.println("execute BeanNameAware#setBeanName");
this.beanName = s;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("execute ApplicationContextAware#setApplicationContext");
this.applicationContext = applicationContext;
}
@Override
public void destroy() throws Exception {
System.out.println("execute DisposableBean#destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("execute InitializingBean#afterPropertiesSet");
}
public void doInit() {
System.out.println("execute User#doInit");
}
public void doDestroy() {
System.out.println("execute User#doDestroy");
}
}
<bean id="user" class="com.xyx.life.User" init-method="doInit" destroy-method="doDestroy">
<property name="name" value="hzq"/>
</bean>
<bean id="myBeanFactoryPostProcessor" class="com.xyx.life.MyBeanFactoryPostProcessor"/>
<bean id="myBeanPostProcessor" class="com.xyx.life.MyBeanPostProcessor"/>
<bean id="myInstantiationAwareBeanPostProcessor" class="com.xyx.life.MyInstantiationAwareBeanPostProcessor"/>
1.2 总体步骤
(1)BeanFactoryPostProcessor
- BeanFactoryPostProcessor可以在实例化bean之前对bean元数据进行修改
- 可以实现多个BeanFactoryPostProcessor,通过设置“order”属性来控制BeanFactoryPostProcessor的执行次序
- BeanFactoryPostProcessor的作用域范围是容器级的。它只和你所使用的容器有关。如果你在容器中定义一个BeanFactoryPostProcessor,它仅仅对此容器中的bean进行后置处理。BeanFactoryPostProcessor不会对定义在另一个容器中的bean进行后置处理,即使这两个容器都是在同一层次上
(2)InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
(3)调用 Bean 构造方法实例化 Bean
(4)InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
(5)InstantiationAwareBeanPostProcessor.postProcessProperties()
(6)利用依赖注入完成 Bean 中所有属性值的配置注入(setXxx)
(7)BeanNameAware.setBeanName
(8)BeanFactoryAware.setBeanFactory
(9)ApplicationContextAware.setApplicationContext
(10)BeanPostProcessor.postProcessBeforeInitialization
(11)InitializingBean.afterPropertiesSet
(12)自定义Init方法
(12)BeanPostProcessor.postProcessAfterInitialization
(13)DisposableBean.destroy
(14)自定义destroy方法
1.3 源码分析
BeanFactoryPostProcessor在AbstractApplicationContext.invokeBeanFactoryPostProcessors会调用所有的BeanFactoryPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
注册BeanPostProcessor,为后面实例化bean调用后置处理器做准备
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
if (beanFactory instanceof AbstractBeanFactory) {
// Bulk addition is more efficient against our CopyOnWriteArrayList there
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
}
else {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}
在创建AbstractAutowireCapableBeanFactory.createBean中,在调用doCreateBean之前,会调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//锁定class,根据设置的class属性或者根据className来解析Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
//在Spring配置中是存在lookup-method和replace-method的,
// 而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
createBean主要完成的功能:
- 根据设置的class属性或者根据className来解析Class。
- 对override属性进行标记及验证,这个主要是Spring配置中是存在lookup-method和replace-method的,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里
- 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作,调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
- 创建bean
创建bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
//AOP就是在这里将advice动态织入bean中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//如果配置了destroy-method,这里需要注册以便于在销毁时候调用
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean的主要功能:
- 如果是单例则需要首先清除缓存
- 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
- 循环依赖检查与处理
- 调用populateBean完成属性填充,在调用set方法之前会调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation和postProcessProperties
- 完成属性填充,会调用initializeBean来初始化bean,初始化过程会调用Aware接口、后置处理器的前置方法、InitializingBean.afterPropertiesSet、自定义init以及后置处理器的后置方法
- 注册DisposableBean。如果配置了destroy-method,这里需要注册以便于在销毁时候调用
至于销毁方法的调用,ConfigurableApplicationContext调用registerShutdownHook会执行相应的销毁方法