所以,看起来 , 整个Bean的销毁步骤都是这哥们儿一个人完成的喽 。
文章插图
不过这个图应该画错了,它把
DestructionAwareBeanPostProcessors
写成了InstantiationAwareBeanPostProcessor
。看看它被调用的构造方法里写了啥:
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,List<DestructionAwareBeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {this.bean = bean;this.beanName = beanName;this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();// 该Bean是不是可调用的DisposableBeanthis.invokeDisposableBean = (bean instanceof DisposableBean &&!beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));// destroy方法名String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);// 和初始化哪里一样,防止destroy方法名和DisposableBean的方法名一样,重复调用if (destroyMethodName != null &&!(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&!beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {// 如果Bean是一个AutoClosable并且自定义的销毁方法名也是close的话this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));if (!this.invokeAutoCloseable) {// 如果不是 , destroyMethodName就使用用户指定的并解析对应方法this.destroyMethodName = destroyMethodName;Method destroyMethod = determineDestroyMethod(destroyMethodName);// 省略一些destroy method参数设置相关的代码this.destroyMethod = destroyMethod;}}// 获取beanPostProcessors(filterPostProcessors会过滤掉所有非DestructionAwareBeanPostProcessor的类)this.beanPostProcessors = filterPostProcessors(postProcessors, bean);this.acc = acc;}
这里就是做了一些初始化工作,把需要的成员变量都解析出来,方便后面destroy
时使用 。然后我们看看
destroy
方法:public void destroy() {// 调用所有DestructionAwareBeanPostProcessor的postProcessBeforeDestructionif (!CollectionUtils.isEmpty(this.beanPostProcessors)) {for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}// 如果是一个disposableBean,调用它的destroyif (this.invokeDisposableBean) {((DisposableBean) this.bean).destroy();}// 如果是AutoCloseable(并且自定义销毁方法名也是close) , 直接调用closeif (this.invokeAutoCloseable) {((AutoCloseable) this.bean).close();}// 否则去调用自定义方法else if (this.destroyMethod != null) {invokeCustomDestroyMethod(this.destroyMethod);}// 有可能存在destroyMethod没解析,但是destroyMethodName有了的情况,解析并调用else if (this.destroyMethodName != null) {Method destroyMethod = determineDestroyMethod(this.destroyMethodName);if (destroyMethod != null) {invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass()));}}}
实战DestructionAwareBeanPostProcessor#创建DestructionAwareBeanPostProcessor
public class MyDestructionProcessor implements DestructionAwareBeanPostProcessor {@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {System.out.println("[+] DestructionProcessor : " + beanName);}}
向工厂中添加BeanPostProcessor
,并销毁Bean:factory.addBeanPostProcessor(new MyDestructionProcessor());factory.destroyBean("workbench", workbench);
结果:Workbench(operator=Person(name=Yudoge))[+] DestructionProcessor : top.yudoge.springserials.basic.beanfactory.beans.Workbench
实战DisposableBean#让Bean实现DisposableBean
@Datapublic class Workbench implements DisposableBean {@Autowiredprivate Person operator;@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean destroy");}}
结果:Workbench(operator=Person(name=Yudoge))[+] DestructionProcessor : top.yudoge.springserials.basic.beanfactory.beans.WorkbenchDisposableBean destroy
实战CustomDestroyMethod#添加自定义销毁方法@Datapublic class Workbench implements DisposableBean {@Autowiredprivate Person operator;@Overridepublic void destroy() throws Exception {System.out.println("DisposableBean destroy");}public void customDestroyMethod() {System.out.println("Custom destroy method...");}}
在BeanDefinition中定义:workbenchRbd.setDestroyMethodName("customDestroyMethod");
结果:Workbench(operator=Person(name=Yudoge))[+] DestructionProcessor : workbenchDisposableBean destroyCustom destroy method...
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 详解AQS中的condition源码原理
- 怎么去巴基斯坦去巴基斯坦时需要注意什么(从中国去巴基斯坦怎么去)
- 有到过伊拉克的人吗应该怎么去(从国内怎样到伊拉克)
- 从ObjectPool到CAS指令
- 蜘蛛的丝是从哪里吐出来的?
- .net 温故知新:【8】.NET 中的配置从xml转向json
- iqoo7电池多大_iqoo7电池多少毫安
- 【lwip】08-ARP协议一图笔记及源码实现
- <一>从指令角度了解函数堆栈调用过程
- 【lwip】07-链路层收发以太网数据帧源码分析