对于类的初始化和实例化。实例化会不会一定是在初始化的基础上呢?之前验证以为实例化之前肯定会初始化,但是好像理解有问题,比如说springioc的bean的生命周期是4阶段,第一阶段是实例化,第三阶段是初始化,这样子不就是说明了初始化也可以在实例化后面了吗?也许之前理解有问题,看看有哪些uu浇浇
2条回答 默认 最新
关注
- 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/644925
- 你也可以参考下这篇文章:spring 使用@Bean修饰的方法,直接调用方法设置对象和用形参注入设置对象一样吗
- 除此之外, 这篇博客: 还记不住Spring Bean的生命周期?看这篇你就知道方法了!中的 四、销毁阶段 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
在容器关闭的时候,会进入Bean的销毁阶段,代码从AbstractApplicationContext的close()方法开始
不急着进入close()方法,先看一下第一节代码中最末尾的方法:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); //如果Bean不是多例且需要在容器关闭时销毁 if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { //给当前Bean绑定一个DisposableBeanAdapter 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)); } } } public void registerDisposableBean(String beanName, DisposableBean bean) { synchronized (this.disposableBeans) { this.disposableBeans.put(beanName, bean); } }
在registerDisposableBeanIfNecessary中,会对每一个需要在容器关闭时进行销毁的单例Bean,绑定对应的DisposableBeanAdapter对象。最后把这些Bean及其DisposableBeanAdapter放入进名称为disposableBeans的map中,以供后续使用。
现在我们进入AbstractApplicationContext的close()方法
一路上兜兜转转,会进入到DefaultSingletonBeanRegistry的destroySingletons方法中
public void destroySingletons() { String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); for (int i = disposableBeanNames.length - 1; i >= 0; i--) { destroySingleton(disposableBeanNames[i]); } //省略部分代码 }
先拿到所有待销毁Bean的名称,挨个调用destroySingleton方法,一直往下走,最终会进入到DefaultSingletonBeanRegistry的destroyBean中
其中核心的一句
// Actually destroy the bean now... bean.destroy();
按照beanName从disposableBeans中获取到bean对应的DisposableBeanAdapter,调用其destroy方法
public void destroy() { //调用被@PreDestroy注解修饰的方法 //具体可以跟进InitDestroyAnnotationBeanPostProcessor类 if (!CollectionUtils.isEmpty(this.beanPostProcessors)) { for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) { processor.postProcessBeforeDestruction(this.bean, this.beanName); } } //如果实现了DisposableBean接口,则调用destroy方法 if (this.invokeDisposableBean) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((DisposableBean) this.bean).destroy(); return null; }, this.acc); } else { ((DisposableBean) this.bean).destroy(); } } //调用xml中自定义的destroy-method方法 if (this.destroyMethod != null) { invokeCustomDestroyMethod(this.destroyMethod); } else if (this.destroyMethodName != null) { Method methodToCall = determineDestroyMethod(this.destroyMethodName); if (methodToCall != null) { invokeCustomDestroyMethod(methodToCall); } } }
到这里,Bean的销毁过程基本就结束了,我们使用一张图来概括下:
- 您还可以看一下 唐世林老师的Java面试题精选集锦课程中的 8、【Spring面试题】什么是bean的自动装配,有哪些装配方式小节, 巩固相关知识点
解决 无用评论 打赏 举报
悬赏问题
- ¥15 rexroth indramotion MTX micro系统轴耦合编程
- ¥20 dify的代码解释器工具和代码执行节点有什么区别?代码解释器工具怎么用?
- ¥100 springboot2.7.x 整合 sharding 的问题
- ¥15 如何通过命令行操作统信360安全浏览器?
- ¥15 upload-labs-master第三关
- ¥15 关于LT3758反激式负压电源,功率三极管烧毁的问题
- ¥20 aruba ap305 CAP转IAP
- ¥20 rockchip rk3588 ffmedia运行异常
- ¥30 如何用 Java 简单系统设计?(相关搜索:服务器|面向对象设计|随机数)
- ¥15 鸿蒙开发(关键词-开发环境)