Spring IoC源码:finishRefresh 完成刷新详解

简介: Spring IoC源码:finishRefresh 完成刷新详解

文章目录

Spring源码系列:

前言

正文

方法1:finishRefresh

方法2:initLifecycleProcessor

方法3:onRefresh

方法4:publishEvent

方法5:multicastEvent

方法6:invokeListener

方法7:doInvokeListener

总结

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍

Spring IOC源码:核心流程介绍

Spring IOC源码:ApplicationContext刷新前准备工作

Spring IOC源码:obtainFreshBeanFactory 详解(上)

Spring IOC源码:obtainFreshBeanFactory 详解(中)

Spring IOC源码:obtainFreshBeanFactory 详解(下)

Spring IOC源码:<context:component-scan>源码详解

Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解

Spring IOC源码:registerBeanPostProcessors 详解

Spring IOC源码:实例化前的准备工作

Spring IOC源码:finishBeanFactoryInitialization详解

Spring IoC源码:getBean 详解

Spring IoC源码:createBean( 上)

Spring IoC源码:createBean( 中)

Spring IoC源码:createBean( 下)

Spring IoC源码:finishRefresh 完成刷新详解

前言

当完成Bean定义信息解析、Bean的创建、初始化流程之后,到最后一个方法finishRefresh完成上下文刷新。

正文

来到refresh()方法中的最后一个方法finishRefresh();

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      // 容器刷新前准备工作
      prepareRefresh();
      // Tell the subclass to refresh the internal bean factory.
      //创建Bean工厂,解析配置
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // bean工厂准备工作
      prepareBeanFactory(beanFactory);
      try {
        //拓展接口,留给子类进行实现拓展
        postProcessBeanFactory(beanFactory);
        // 注册执行,BeanFactoryPostProcessor
        invokeBeanFactoryPostProcessors(beanFactory);
        // 注册创建BeanPostProcessor
        registerBeanPostProcessors(beanFactory);
        // 这个方法主要作用就是使用国际化,定制不同的消息文本,比如定义了一个Person的Bean,它有name属性,我们需要在不同的国家展示对应国家所在语言名称,这时候就可以使用国际化了。
        initMessageSource();
        // Initialize event multicaster for this context.
        //初始化应用事件广播器
        initApplicationEventMulticaster();
        // Initialize other special beans in specific context subclasses.
        //拓展接口,留给子类进行实现拓展,springboot就对该方法进行了处理
        onRefresh();
        // Check for listener beans and register them.
        //将内部的、以及我们自定义的监听器添加到缓存中,为后续逻辑处理做准备。还有添加事件源到缓存中。
        registerListeners();
        // Instantiate all remaining (non-lazy-init) singletons.
        //实例化剩下非懒加载的Bean
        finishBeanFactoryInitialization(beanFactory);
        // Last step: publish corresponding event.
        //使用应用事件广播器推送上下文刷新完毕事件(ContextRefreshedEvent )到相应的监听器。
        finishRefresh();
      }
      catch (BeansException ex) {
        if (logger.isWarnEnabled()) {
          logger.warn("Exception encountered during context initialization - " +
              "cancelling refresh attempt: " + ex);
        }
        // Destroy already created singletons to avoid dangling resources.
        //执行相关销毁方法
        destroyBeans();
        // Reset 'active' flag.
        //重置上下文刷新状态
        cancelRefresh(ex);
        // Propagate exception to caller.
        throw ex;
      }
      finally {
        // Reset common introspection caches in Spring's core, since we
        // might not ever need metadata for singleton beans anymore...
        resetCommonCaches();
      }
    }
  }

finishRefresh(),见方法1详解

方法1:finishRefresh

  protected void finishRefresh() {
    // Clear context-level resource caches (such as ASM metadata from scanning).
    //清除该资源加载器中的所有资源缓存
    clearResourceCaches();
    // Initialize lifecycle processor for this context.
    //初始化LifecycleProcessor。
    initLifecycleProcessor();
    // Propagate refresh to lifecycle processor first.
    //调用LifecycleProcessor的onRefresh方法进行刷新
    getLifecycleProcessor().onRefresh();
    // 发布事件
    publishEvent(new ContextRefreshedEvent(this));
    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
  }

initLifecycleProcessor(),见方法2详解

getLifecycleProcessor().onRefresh(),见方法3详解

publishEvent(new ContextRefreshedEvent(this)),见方法4详解

方法2:initLifecycleProcessor

  protected void initLifecycleProcessor() {
    //获取BeanFactory工厂
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    //判断是否存在名称为lifecycleProcessor的Bean或定义信息
    if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
      //获取或创建LifecycleProcessor
      this.lifecycleProcessor =
          beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
      if (logger.isTraceEnabled()) {
        logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
      }
    }
    else {
      //bean工厂中不存在该bean的信息,则创建一个默认的
      DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
      defaultProcessor.setBeanFactory(beanFactory);
      this.lifecycleProcessor = defaultProcessor;
      //注册添加到一级缓存中
      beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
      if (logger.isTraceEnabled()) {
        logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
            "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
      }
    }
  }

方法3:onRefresh

  public void onRefresh() {
    startBeans(true);
    this.running = true;
  }
private void startBeans(boolean autoStartupOnly) {
    //获取Lifecycle类型的bean集合
    Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
    Map<Integer, LifecycleGroup> phases = new HashMap<>();
    lifecycleBeans.forEach((beanName, bean) -> {
      //autoStartupOnly 为true时,代表是容器自动启动调用,这时只有SmartLifecycle 类型且isAutoStartup为TRUE才会调用
      //如果autoStartupOnly 为false,代表是手动调用,会调用所有的Lifecycle
      if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
        //获取阶段值,即优先级值。如果有实现Phased接口,则通过getPhase方法返回数值,值越小则排序越前
        int phase = getPhase(bean);
        //判断容器中是否已存在,不存在则创建LifecycleGroup 类型对象
        LifecycleGroup group = phases.get(phase);
        if (group == null) {
          group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
          phases.put(phase, group);
        }
        group.add(beanName, bean);
      }
    });
    if (!phases.isEmpty()) {
      List<Integer> keys = new ArrayList<>(phases.keySet());
      //排序
      Collections.sort(keys);
      //遍历调用
      for (Integer key : keys) {
        phases.get(key).start();
      }
    }
  }

方法4:publishEvent

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
    Assert.notNull(event, "Event must not be null");
    // Decorate event as an ApplicationEvent if necessary
    //判断事件是否继承了ApplicationEvent接口
    ApplicationEvent applicationEvent;
    if (event instanceof ApplicationEvent) {
      applicationEvent = (ApplicationEvent) event;
    }
    else {
      //将事件封装成PayloadApplicationEvent类型的事件
      applicationEvent = new PayloadApplicationEvent<>(this, event);
      //设置事件类型
      if (eventType == null) {
        eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
      }
    }
    // Multicast right now if possible - or lazily once the multicaster is initialized
    if (this.earlyApplicationEvents != null) {
      this.earlyApplicationEvents.add(applicationEvent);
    }
    else {
      //使用多播器发布事件
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    }
    // Publish event via parent context as well...
    //使用父上下文进行发布事件
    if (this.parent != null) {
      if (this.parent instanceof AbstractApplicationContext) {
        ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
      }
      else {
        this.parent.publishEvent(event);
      }
    }
  }

getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType),见方法5详解

方法5:multicastEvent

  public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    //获取事件源类型
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    //根据事件类型获取对应类型的监听器
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      //调用监听器的onApplicationEvent方法
      if (executor != null) {
        executor.execute(() -> invokeListener(listener, event));
      }
      else {
        invokeListener(listener, event);
      }
    }
  }

invokeListener(listener, event)),见方法6详解

方法6:invokeListener

  protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    //获取错误处理器
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
      try {
      //调用监听器处理方法
        doInvokeListener(listener, event);
      }
      catch (Throwable err) {
        errorHandler.handleError(err);
      }
    }
    else {
      doInvokeListener(listener, event);
    }
  }

doInvokeListener(listener, event),见方法7详解

方法7:doInvokeListener

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    try {
      //调用监听器的onApplicationEvent方法,并传入事件
      listener.onApplicationEvent(event);
    }
    catch (ClassCastException ex) {
      String msg = ex.getMessage();
      if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
        // Possibly a lambda-defined listener which we could not resolve the generic event type for
        // -> let's suppress the exception and just log a debug message.
        Log logger = LogFactory.getLog(getClass());
        if (logger.isTraceEnabled()) {
          logger.trace("Non-matching event type for listener: " + listener, ex);
        }
      }
      else {
        throw ex;
      }
    }
  }

总结

Spring IOC中refresh()所有方法都讲解完了,这里面的内容非车多,花了不少时间在看,但是感觉还是比较粗糙,文章中有很多点理解得不是很到位,如果大家有更好的见解,欢迎指点评论。学习IOC过程是非常枯燥的,但是耐心去看真的能发现这个框架设计真的很厉害,拓展性做得很好,有很多地方值得我们在工作中进行参考开发。后续会发布Spring 系列的其它文章,如AOP,只有不断的学习,才能加深对Spring框架的理解。

————————————————

版权声明:本文为CSDN博主「@猪大肠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_45031612/article/details/128193344

目录
相关文章
|
2月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
4月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
8月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
535 70
|
6月前
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
198 1
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
7月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
9月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
9月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
259 0
|
Java 关系型数据库 数据库连接
Spring源码解析--深入Spring事务原理
本文将带领大家领略Spring事务的风采,Spring事务是我们在日常开发中经常会遇到的,也是各种大小面试中的高频题,希望通过本文,能让大家对Spring事务有个深入的了解,无论开发还是面试,都不会让Spring事务成为拦路虎。
332 1

热门文章

最新文章