Spring源码解析-9、Bean的生命周期

Bean的完整生命周期 图序

Bean的完整生命周期如下图:
在这里插入图片描述
在这里插入图片描述
如果容器注册了上述接口,就会按如上顺序执行。

今天先来看Bean级别的接口

BeanFactoryAware、BeanNameAware

BeanFactoryAware:

public interface BeanFactoryAware extends Aware {
    void setBeanFactory(BeanFactory var1) throws BeansException;
}

用于在Bean注入时使Bean感知加载Bean的BeanFactory,可以在该Bean中通过BeanFactory做一些操作,比如获取其他Bean。

BeanNameAware

public interface BeanNameAware extends Aware {
    void setBeanName(String var1);
}

用于在Bean注入时使Bean得到在容器中的名字。

使用案例:

public class Test implements BeanNameAware,BeanFactoryAware {
    @Override
    public void setBeanName(String s) {
        System.out.println("获取BeanName = "+s);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("获取BeanFactory = "+beanFactory);
    }
}

spring的配置文件中配置:
<bean class="com.raycloud.dmj.data.utils.Test"/>


main方法执行:
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

输出结果:

获取BeanName = com.raycloud.dmj.data.utils.Test#0

获取BeanFactory = org.springframework.beans.factory.support.DefaultListableBeanFactory@12cb1b59: defining beans [com.raycloud.dmj.data.utils.Test#0]; root of factory hierarchy
这个BeanFactory在这里就是ApplicationContext的父工厂DefaultListableBeanFactory。

InitializingBean和DisposableBean

InitializingBean:

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

在IOC容器为Bean的属性设置完成后执行。
DisposableBean:

public interface DisposableBean {
    void destroy() throws Exception;
}

在Bean销毁时执行

使用案例:

public class Test implements InitializingBean,DisposableBean {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("设置name");
        this.name = name;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}

spring的配置:
<bean class="com.raycloud.dmj.data.utils.Test">
    <property name="name" value="ycf"/>
</bean>
main方法执行
 ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");

得到结果:
设置name
afterPropertiesSet

main方法执行
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
((ClassPathXmlApplicationContext) context).close();

得到结果:
设置name
afterPropertiesSet
destroy

<bean>的init-method和destroy-method

除了上面通过两个接口来实现Bean初始化和销毁的操作,
还有通过自定义的初始化和销毁方法来实现,注意通过接口实现和通过自定义的实现两者是共存的,且 InitializingBean的afterPropertiesSet先于 bean标签的init-method[或者注解PostConstruct] 执行,DisposableBean的detory先于bean标签的destory-method[或者注解PreDestroy].

public class Test implements InitializingBean,DisposableBean {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("设置name");
        this.name = name;
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
    
    public void initMethod(){
        System.out.println("自定义init");
    }
    
    public void destoryMethod(){
        System.out.println("自定义destory");
    }
}

spring配置:
<bean class="com.raycloud.dmj.data.utils.Test" init-method="initMethod" destroy-method="destoryMethod">
    <property name="name" value="ycf"/>
</bean>
main执行:
 ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
 ((ClassPathXmlApplicationContext) context).close();

得到结果:
设置name
afterPropertiesSet
自定义init
destroy
自定义destory

源码分析

初始化
注意以上的初始化接口,都是在Bean初始化完毕,并且属性设置完毕后才会执行的,它的入口在doCreateBean中

//设置属性
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);

因此对Bean的初始化,我们需要着重关注initializeBean

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;
		//Bean的后置处理器在执行初始化前,做一些处理。
		不是今天 的重点
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
		//执行初始化方法
			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()) {
		//Bean的后置处理器,在初始化后做一些操作
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

invokeAwareMethods:
这个方法很简单,就是去回调接口的方法
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);
			}
		}
	}

invokeInitMethods:
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 (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
			//执行InitializingBean的afterPropertiesSet
				((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);
			}
		}
	}

如上初始化的过程,先执行Aware的接口,使Bean感知到容器、Bean名称甚至类加载器。
然后执行初始化,先执行InitializingBean的afterPropertiesSet,在执行自定义的初始化方法。

至于初始化前后的BeanPostProcessor并不属于Bean的生命周期,而是属于容器的,因此不再一起去讲。

销毁
销毁时在容器销毁的时候才会去销毁Bean,并且需要注意的是只有单例Bean才需要销毁,如果是原型类型的,本身就不由spring容器缓存,就不可能去销毁。
容器的destory方法最终调用到DisposableBeanAdapter的destroy

public void destroy() {
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}

		if (this.invokeDisposableBean) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
			}
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {			//执行DisposableBean的destory
						((DisposableBean) this.bean).destroy();
						return null;
					}, this.acc);
				}
				else {
					((DisposableBean) this.bean).destroy();
				}
			}
			catch (Throwable ex) {
				String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
				if (logger.isDebugEnabled()) {
					logger.info(msg, ex);
				}
				else {
					logger.info(msg + ": " + ex);
				}
			}
		}

//执行自定义的销毁方法
		if (this.destroyMethod != null) {
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToCall = determineDestroyMethod(this.destroyMethodName);
			if (methodToCall != null) {
				invokeCustomDestroyMethod(methodToCall);
			}
		}
	}

如上也看得到销毁Bean的过程确实是先执行DisposableBean的destory,在执行自定义的销毁方法。

猜你喜欢

转载自blog.csdn.net/qq_28605513/article/details/85696413