Spring把bean分为基础组件和自定义业务类型,对于基础组件类型的bean有的是在框架层直接实例化(类似BeanFactoryProcessor或Scanner等),也有一些和普通bean一样交给上下文统一管理,我们今天主要分析普通业务bean的生命周期管理,我们都知道Spring对于bean的管理主要分为类加载或者扫描解析成BeanDefinition,然后实例化前置处理、实例化、实例化后置处理,使用和销毁:
图注:lifecycle
本篇我们主要围绕三个注解@PostConstruct/@PreDestroy/@Resource,两个接口InitializingBean/DisposableBean和一个类CommonAnnotationBeanPostProcessor展开分析.
使用Spring作为应用的基础架构,我们都或多或少了解过其强大的扩展性,举个例子,我们可以在任何一个bean的生命周期的任何节点做自定义或者定制化逻辑处理(基础组件类除外),比如我们会在一些业务bean初始化完成后和使用之前做一些内部数据初始化或者本地缓存处理,那么我们可以实现InitializingBean重写afterPropertiesSet方法或者用@PostConstruct注解标注方法,那么Spring容器会在启动时bean实例化之后调用afterPropertiesSet或者@PostConstruct的方法,又或者我们在上下文关闭的之前需要释放一些动态资源,那么我们就可以实现DisposableBean接口重写destroy方法或者用@PreDestroy注解标注方法,在应用上下文关闭时会触发调用destroy和@Predestroy标记方法逻辑来完成资源释放.
@Component
@Slf4j
public class Test implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
log.info("afterPropertiesSet...");
}
@PostConstruct
public void postConstruct() {
log.info("postConstruct...");
}
@Override
public void destroy() throws Exception {
log.info("destroy...");
}
@PreDestroy
public void preDestroy() {
log.info("preDestroy...");
}
}
图注:result
图注:result
有一个细节不知道有没有注意到,编码的时候我故意把注解标记的方法都写到了接口实现方法的后边,但是实际运行的时候,注解标记的方法都是先于接口方法执行的,所以很明显调用顺序和编码顺序无关,这样很方便地我们就对bean实例化之后和销毁之前做了一些自定义逻辑处理了.
这些能力由CommonAnnotationBeanPostProcessor支持实现:
avatar 该类本质上是一个BeanPostProcessor,继承了InitDestroyAnnotationBeanPostProcessor类,实现了DestructionAwareBeanPostProcessor和InstantiationAwareBeanPostProcessor接口,拥有对bean生命周期管理的能力.
上一篇文章@Autowired注解原理分析 中描述到应用启动初始化上下文AnnotationConfigServletWebServerApplicationContext时会调用AnnotationConfigUtils.registerAnnotationConfigProcessors:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
...省略
return beanDefs;
}
这里注册了BeanDefinition,在上下文refresh的时候进行了实例化:
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
前边已经注册了RootBeanDefinition,这里调用beanFactory.getBean会进行实例化.
既然是和bean生命周期相关,那么我们直接把AbstractAutowireCapableBeanFactory#doCreateBean作为切入点:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...省略部分代码
// 1.实例化bean
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 2.允许后处理器修改合并的bean定义
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;
}
}
...省略部分代码
// 3.初始化bean
Object exposedObject = bean;
try {
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);
}
}
...省略部分代码
// 4.注册销毁逻辑
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
代码中做了注释,涉及了bean生命周期的各个节点:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
CommonAnnotationBeanPostProcessor实现了MergedBeanDefinitionPostProcessor接口:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
目的是把@PostConstruct和PreDestroy以及@Resource等注册到BeanDefinition中供后续调用. 初始化bean属性populateBean方法我们前一篇分析过AutowiredAnnotationBeanPostProcessor,而CommonAnnotationBeanPostProcessor处理@Resource、@WebServiceRef和@EJB属性注入,逻辑大致相同,分别调用EjbRefElement/WebServiceRefElement/ResourceElement的inject方法进行属性注入:
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
接着我们看初始化方法调用:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//1.调用Aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//2.调用BeanPostProcessor的postProcessBeforeInitialization方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//3.调用InitializingBean#afterPropertiesSet或者自定义init-method
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokeAwareMethods是把beanName、BeanClassLoader和BeanFactory注入,applyBeanPostProcessorsBeforeInitialization会调用CommonAnnotationBeanPostProcessor父类InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
调用buildLifecycleMetadata返回LifecycleMetadata:
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
List<LifecycleElement> initMethods = new ArrayList<>();
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}
由于CommonAnnotationBeanPostProcessor默认构造器传入的initAnnotationType和destroyAnnotationType分别是PostConstruct和PreDestroy,所以此处返回的就是包装PostConstruct和PreDestroy注解方法的生命周期元数据,然后再调用invokeInitMethods方法:
public void invokeInitMethods(Object target, String beanName) throws Throwable {
Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
Collection<LifecycleElement> initMethodsToIterate =
(checkedInitMethods != null ? checkedInitMethods : this.initMethods);
if (!initMethodsToIterate.isEmpty()) {
for (LifecycleElement element : initMethodsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
}
element.invoke(target);
}
}
}
然后通过invokeInitMethods方法调用InitializingBean接口实现的afterPropertiesSet方法和用户自定义的init-method方法:
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) 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);
}
}
}
然后会调用BeanPostProcessor#postProcessAfterInitialization,CommonAnnotationBeanPostProcessor没有自定义实现,如果用户有自定义实现会调用自定义逻辑. 回到doCreateBean方法最后,会调用registerDisposableBeanIfNecessary注册bean销毁逻辑:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
该方法会把bean的销毁逻辑封装成DisposableBeanAdapter适配器注册到disposableBeans或者Scope中(非单例),我们大部分场景都使用单例,DisposableBeanAdapter实现了DisposableBean接口,触发bean销毁逻辑的时候会调用DisposableBeanAdapter的destroy方法,看一下DisposableBeanAdapter封装:
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
this.destroyMethod = determineDestroyMethod(destroyMethodName);
if (this.destroyMethod == null) {
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = this.destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
}
}
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
包含了DisposableBean接口,自定义销毁方法和DestructionAwareBeanPostProcessor逻辑.
前边分析了bean的初始化逻辑和销毁逻辑的注册,接下来我们就分析一下销毁逻辑的调用时机;在Spring应用启动的时候会调用refreshContext:
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
然后调用AbstractApplicationContext#registerShutdownHook:
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
这里就是利用java原生特性,定义并添加钩子逻辑,在应用上下文关闭的时候触发关闭操作doClose:
protected void doClose() {
// Check whether an actual close attempt is necessary...
if (this.active.get() && this.closed.compareAndSet(false, true)) {
if (logger.isDebugEnabled()) {
logger.debug("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// 1.发送上下文关闭事件
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
//2.停止所有实现Lifecycle接口的bean
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
}
// Destroy all cached singletons in the context's BeanFactory.
//3.销毁所有的单例bean
destroyBeans();
// Close the state of this context itself.
//4.关闭bean工厂
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
//5.子类做最后的自定义清理动作,比如ServletWebServerApplicationContext关闭tomcat或者其他容器
onClose();
// Reset local application listeners to pre-refresh state.
if (this.earlyApplicationListeners != null) {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Switch to inactive.
//6.切换成非活跃状态
this.active.set(false);
}
}
销毁bean的操作是第三步,会调用DefaultListableBeanFactory的destroySingletons方法进行销毁操作:
@Override
public void destroySingletons() {
super.destroySingletons();
this.manualSingletonNames.clear();
clearByTypeCache();
}
然后调用父类DefaultSingletonBeanRegistry#destroySingletons:
public void destroySingletons() {
...省略
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
...省略
}
看到this.disposableBeans就比较熟悉了,在AbstractAutowireCapableBeanFactory#doCreateBean方法最后调用registerDisposableBeanIfNecessary把销毁逻辑封装成DisposableBeanAdapter放入DefaultSingletonBeanRegistry的disposableBeans中:
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
接着上边看,会遍历disposableBeanNames并调用destroySingleton:
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
先从disposableBeans中移除DisposableBean,然后调用destroyBean:
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
//1.触发依赖的bean销毁逻辑
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
//2.实际触发销毁逻辑
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isInfoEnabled()) {
logger.info("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
//3.触发包含的bean销毁逻辑
Set<String> containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
//4.将自己从被依赖的bean依赖关系中移除
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
//5.移除bean的准备依赖信息
this.dependenciesForBeanMap.remove(beanName);
}
由于disposableBeans中存储的都是DisposableBeanAdapter实例,所以会调用DisposableBeanAdapter#destory:
@Override
public void destroy() {
//1.先调用DestructionAwareBeanPostProcessor后置销毁逻辑
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
//2.调用bean实现的DisposableBean#destroy逻辑
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) 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);
}
}
}
//3.调用自定义销毁逻辑destroy-method
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToCall = determineDestroyMethod(this.destroyMethodName);
if (methodToCall != null) {
invokeCustomDestroyMethod(methodToCall);
}
}
}
DisposableBeanAdapter的销毁逻辑做了排序,优先调用DestructionAwareBeanPostProcessor的 postProcessBeforeDestruction方法,然后调用bean自定义实现的DisposableBean#destroy,最后调用自定义销毁逻辑,CommonAnnotationBeanPostProcessor继承于InitDestroyAnnotationBeanPostProcessor,父类实现DestructionAwareBeanPostProcessor接口重写了postProcessBeforeDestruction方法:
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeDestroyMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
这里就是调用@PreDestroy注解的方法,也就是说对于销毁逻辑的执行顺序:@PreDestroy->DisposableBean->destroy-method. 到这里bean的销毁逻辑和执行时机以及顺序就分析完了,再回顾一下初始化逻辑以及执行顺序: Aware -> BeanPostProcessor#postProcessBeforeInitialization也就是@PostConstruct -> InitializingBean#afterPropertiesSet -> init-method -> BeanPostProcessor#postProcessAfterInitialization. 那把初始化和销毁串联起来我们就可以得出如下图更清晰完整的bean生命周期节点:
图注:lifecycle
通过本篇文章的分析,我们了解了@PostConstruct/@PreDestroy/InitializingBean/DisposableBean的工作原理、触发时机和顺序,以及Spring内置组建的强大和高扩展性,对于需要基于bean生命周期做一些初始化或者销毁时资源释放操作非常简单易用,对于基于注解和实现接口的两种方式,从某种程度上来说@PostConstruct和@PreDestroy更推荐使用,因为他们是J2EE规范,而基于Spring作为基础架构的应用来说,使用InitializingBean和DisposableBean也无可厚非,并且Spring提供了很多BeanPostProcessor供自定义扩展,我们可以基于具体业务场景做很多定制化事情.
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!