xin麒 2023-05-01 13:07 采纳率: 0%
浏览 17

Java实例化一定在初始化后面吗

对于类的初始化和实例化。实例化会不会一定是在初始化的基础上呢?之前验证以为实例化之前肯定会初始化,但是好像理解有问题,比如说springioc的bean的生命周期是4阶段,第一阶段是实例化,第三阶段是初始化,这样子不就是说明了初始化也可以在实例化后面了吗?也许之前理解有问题,看看有哪些uu浇浇

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-05-01 16:17
    关注
    • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: 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的自动装配,有哪些装配方式小节, 巩固相关知识点
    评论

报告相同问题?

问题事件

  • 创建了问题 5月1日

悬赏问题

  • ¥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 鸿蒙开发(关键词-开发环境)