spring源码-容器refresh

news2024/9/27 7:20:07

spring源码

铺垫

1.xml信息封装

我们可以预测的大致顺序
image-20221105121213650

xml里的bean 封装成对象定义信息更容易进一步的 创建 注入

image-20221105125946001

BeanDefinition的属性:可以看出是对xml里信息的封装

public interface BeanDefinitionReader 定义规范

image-20221105125946001

2.使用反射

为什么不用new创建对象?而用反射

使用反射可以获取到类的所有属性 所有方法 所有的构造器 所有注解 等

灵活 动态创建

3 .bean的作用范围

bean的作用范围

默认单例

image-20221105123426868

反射的3种方法

image-20221105124428339

4.bpp和bfpp的区别 和使用

bpp和bfpp的区别

image-20221105130409827

bfpp的使用范围

image-20221105130553189

自己写一个bean工厂后置处理

image-20221105130739218

使用beanFactory的方法可以自定义处理 拿到BeanDefinition 进行修改

使用自己的这个 bean工厂后置处理:

配置文件配置

image-20221105130956967

之后就可使用了 在启动项目后就会生效

5.实例化和初始化

创建对象 --> 实例化和初始化

image-20221105155415897

6 .实例化的流程,Aware接口

实例化的流程

image-20221105160932950

  1. init-method在哪? 如果不定义的话就是什么都不干

使用案例:

image-20221105155541894

image-20221105155632361

  1. Aware到底是什么接口?

例子

实现了BeanNameAware接口,必须实现setBeanName(String beanName)方法,然后自己定义一个成员变量在setBeanName方法中{this.beanName=beanName}; 这样就拿到了beanName。

例子二

实现了ApplicationContextAware接口,定义一个成员变量在setApplicationContext方法中{this.applicationContext=applicationContext};

先拿到哪个 就对实现哪个接口

image-20221105171521979

相关:如果在实现了某个aware 对调用对应的方法

image-20221105171337175

image-20221105155838030

7. BeanPostProcess.before和.after

BeanPostProcess.before和BeanPostProcess.after的作用是什么?

aop的实现是实现了PostProcess接口 然后写了after方法 在里面使用代理模式 创建了代理对象

8.监听器 广播器

在上面的实例化到完整对象各个阶段之间

image-20221105182720874

image-20221106183920803

image-20221105163351678

9.FactoryBean和BeanFactory的区别

了解 FactoryBean

FactoryBean和BeanFactory的区别

image-20221105194925212

BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似 spring整体流程

public class A implements FactoryBean<B> {
	
    @Override
    public B getObject() throws Exception {
        return new B();
    }

    @Override
    public Class<?> getObjectType() {
        return A.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }


}
  public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean1.xml");

        A aBean1 =(A) applicationContext.getBean("&a");
        System.out.println("aBean = " + aBean1);
      	//加&符号 拿到的工厂本身 所以拿到的是A类的对象

        A aBean2 =(A) applicationContext.getBean("a");
        System.out.println("aBean = " + aBean2);
        //class spring_ioc.test.B cannot be cast to class spring_ioc.test.A  因为默认调用的getObject 所以拿到了B类的对象

        B bObject = aBean1.getObject();
        System.out.println("aOobject = " + bObject);
     

    }

    <bean id="a" class="spring_ioc.test.A">

    </bean>

了解:

image-20221105171842526

比如bfpp不是一个方法 其实也是一个容器对象 是一个bean

整体代码简要分析

spring整体流程大纲图

image-20221105200524886

spring整体流程大纲 代码调用顺序简要分析

从new ClassPathXmlApplication()开始 到底干了点啥?
在这里插入图片描述

下面简单概括一下上面的初始化步骤

  1. prepareRefresh : 初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。在某些情况下项目的使用需要读取某些系统变量,那么在启动时候,就可以通过准备函数来进行参数的校验。
  2. obtainFreshBeanFactory :初始化BeanFactory,并进行XML 文件读取(如果需要的话)。 这一步之后ApplicationContext就具有BeanFactory 所提供的功能,也就是可以进行Bean的提取等基础操作了。
  3. prepareBeanFactory :对BeanFactory 进行各种功能填充。
  4. postProcessBeanFactory : 对 BeanFactory 做额外处理。默认没有实现
  5. invokeBeanFactoryPostProcessors : 激活各种BeanFactory 处理器(调用了各种BeanFactoryPostProcessor)。其中最为关键的是 ConfigurationClassPostProcessor ,在这里完成了配置类的解析,生成注入容器中的bean 的 BeanDefinition。解析@Configuratiqn、@Bean、@lmport、 @PropertySource
  6. registerBeanPostProcessors :注册和创建拦截bean创建的bean处理器。BeanPostProcessor 在这一步已经完成了创建。
  7. initMessageSource :为上下文初始化Message 源,即对不同语言的消息体进行国际化处理
  8. initApplicationEventMulticaster :初始化应用消息广播器,并放入"applicationEventMulticaster" bean 中
  9. onRefresh :留给子类来初始化其他bean
  10. registerListeners :在所有注册的bean中查找listener bean,注册到消息广播器中
  11. finishBeanFactoryInitialization :初始化剩下的实例(非惰性),在这里调用了getBean方法,创建了非惰性的bean实例
  12. finishRefresh :完成刷新过程,通知生命周期处理器 lifecycleProcesseor 刷新过程,同时发出ContextRefreshEvent 通知别人。

源码下载教程spring源码使用了gradle管理

源码:

  1. 调用同名构造
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
   this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {

   super(parent);
    //setConfigLocations(configLocations)方法用来设置配置路径, 支持多个配置文件以数组方式同时传入
   setConfigLocations(configLocations);
   if (refresh) {
      refresh();
   }
}
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFacto ry(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         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();
      }
   }
}

3.1

protected void prepareRefresh() {
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isInfoEnabled()) {
      logger.info("Refreshing " + this);
   }

   // Initialize any placeholder property sources in the context environment
   initPropertySources();

   // Validate that all properties marked as required are resolvable
   // see ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();

   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

3.2

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //--->
   if (logger.isDebugEnabled()) {
      logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
   }
   return beanFactory;
}
protected DefaultListableBeanFactory createBeanFactory() {
   return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 
   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}
  1. finishBeanFactoryInitialization(beanFactory);

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
       // Initialize conversion service for this context.
        //ConversionService是一个服务接口用于类型转换,这也是转换系统的入口点。 这一步没有做什么处理
       if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
             beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
          beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
       }
    
       //
       if (!beanFactory.hasEmbeddedValueResolver()) {
          beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
             @Override
             public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
             }
          });
       }
    
       //  先获取实现了LoadTimeWeaverAware接口的bean名称,LoadTimeWeaverAware是类加载时织入的意思。getBean则是让实现LoadTimeWeaverAware的对象提前实例化。
       String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
       for (String weaverAwareName : weaverAwareNames) {
          getBean(weaverAwareName);
       }
    
       // Stop using the temporary ClassLoader for type matching.
       beanFactory.setTempClassLoader(null);
    
       // Allow for caching all bean definition metadata, not expecting further changes.
       beanFactory.freezeConfiguration();
    
       // Instantiate all remaining (non-lazy-init) singletons.
       beanFactory.preInstantiateSingletons();
    }
    

三级缓存

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

黑马相关面试教学

image-20221228161228775
就是准备了一个environment 是ApplicationContext的一个成员变量,Environment中就是一些后续可能用到的键值信息,比如:application.properties中的

image-20221228164742472

beanFactory也作为了ApplicationContext的一个成员变量,ApplicationContext继承了BeanFactory

但是在使用时 是这种组合关系

image-20221228171353770

右边绿色新多的就是在第3步完成的

image-20221228171628332

image-20221228171950555

多加了一些beanDefinition

image-20221230204630189

注册了并没有用到它呢,在实例化、依赖注入、初始化阶段 才会用到 可能在11步

image-20221231171220301

image-20221231171650826

image-20221231171802776

体现了模板方法设计模式

image-20221231174805506

image-20221231172630837

在beanDefinitionMap非延迟单例对象 在这个时候创建出来bean (Beanpp 就会派上用场

image-20221231175438863

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/139988.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NXP EMDA学习(1):TCD寄存器详解

eDMA(Enhanced DMA)即增强型DMA&#xff0c;它是NXP芯片中独有的功能&#xff0c;其最重要的一个特性也是eDMA的核心就是TCD(Transfer Control Descriptor)即传输控制描述符。所以&#xff0c;我们就来看一下这个结构体中各个字段的内容的含义&#xff0c;对这些字段有一个基础…

位置检测有哪些传感器可以用?(带磁编码器AS5600代码)

常见的有三种 编码器、霍尔传感器、磁传感器。 编码器一般指AB相正交脉冲的增量器件&#xff0c;有的还会有一个Z相信号&#xff0c;用来指示零位&#xff1b; 霍尔传感器一般是指ABC三个成120度角度间隔排列的器件&#xff0c;这种传感器一般集成在电机内部&#xff0c;电机…

[Amazon]人工智能入门学习笔记---AI-机器学习-深度学习

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &a…

基于模型预测控制的波浪能转换器(WEC)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Flink简介

Flink 系列教程传送门 第一章 Flink 简介 第二章 Flink 环境部署 第三章 Flink DataStream API 第四章 Flink 窗口和水位线 第五章 Flink Table API&SQL 第六章 新闻热搜实时分析系统 前言 流计算产品实时性有两个非常重要的实时性设计因素&#xff0c;一个是待计算…

基于 Docker 的 Neo4j 部署及数据备份与恢复

目录一、部署二、验证三、备份3.1 离线备份3.2 在线备份3.3 社区版备份一、部署 1、pull 镜像 docker pull neo4j:4.4.16-community2、创建目录 mkdir -p /home/data/neo4j/{data,logs,conf,import,db-backup}3、运行容器 docker run -itd \--name neo4j \--restart always…

openwrt-看门狗watchdog

一、硬件watchdog和软件watchdog Linux内核不仅为各种不同类型的watchdog硬件电路提供了驱动&#xff0c;还提供了一个基于定时器的纯软件watchdog驱动&#xff0c;软件watchdog基于内核的定时器实现&#xff0c;当内核或中断出现异常时&#xff0c;软件watchdog是无法复位系统…

二叉树17:路径总和

主要是我自己刷题的一些记录过程。如果有错可以指出哦&#xff0c;大家一起进步。 转载代码随想录 原文链接&#xff1a; 代码随想录 leetcode链接&#xff1a;112. 路径总和 112. 路径总和 题目&#xff1a; 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判…

判断图中有没有证件图片

整体解决思路: 前提:拍摄场景光线稳定,证件没有放在图像边缘;且图片使用的证件阅读器拍摄的红外图片,采用了开灯和关灯各拍摄一张图片,图像相减,进行了背景去除; 1)使用二值化和膨胀腐蚀以及sobel算子等进行图像的预处理; 2)进行凸包计算,通过角度,进行证件区域…

缓存穿透,缓存雪崩,缓存击穿的超详解

文章目录1、缓存穿透问题的解决思路2、缓存雪崩问题及解决思路3、缓存击穿问题及解决思路1、缓存穿透问题的解决思路 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库&#xff0c;失去了缓存的意…

pytorch数据dataset的三种读取方式

文章目录1.自带的datasets2.ImageFolder3.自己创建的dataset&#xff08;用的多&#xff09;1.自带的datasets pytorch自带的数据集 具体数据集如下&#xff1a; 用法&#xff1a; 可以用的功能 2.ImageFolder 文件形式如下时用此&#xff1a;&#xff08;一个文件下只…

MyBatis框架 入门案例

二刷复习简介MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Jav…

磨金石教育科技摄影技能干货分享|艺术摄影的本源是创作,核心是表达

艺术类的作品一直都有一个风格&#xff0c;那就是抽象。特别是摄影领域&#xff0c;一幅作品如果缺乏创意&#xff0c;只是展现现实的景物&#xff0c;那么很容易就变成了纪实摄影或者风光摄影。因此&#xff0c;要想让作品突出艺术性&#xff0c;就要再原有的画面上&#xff0…

Exynos_4412——中断处理(中断学习结尾篇)

目录 一、ARM的异常处理机制 1.1异常概念 1.2异常处理机制 1.3ARM异常源 1.4异常模式 1.5ARM异常响应 1.6异常向量表 1.7异常返回 1.8IRQ异常举例 二、工程模板代码结构 三、中断处理框架搭建 四、中断处理程序 五、用key3再试一试 前景提要&#xff1a; Exynos_…

利用Model Inspector的建模规则检查

利用Model Inspector的规则检查 Model Inspector是一种基于模型的软件静态验证自动化解决方案。通过对模型进行规则检查,开发人员的工作成本将减少,开发效率将会大大提高。 Model Inspector支持各种行业标准建模规范,对违反规范进行检查。 用户可通过dashboard获知模型质量指标…

滴滴前端一面常考手写面试题合集

使用Promise封装AJAX请求 // promise 封装实现&#xff1a; function getJSON(url) {// 创建一个 promise 对象let promise new Promise(function(resolve, reject) {let xhr new XMLHttpRequest();// 新建一个 http 请求xhr.open("GET", url, true);// 设置状态的…

磨金石教育摄影技能干货分享|优秀摄影作品欣赏——艺术的表达

艺术摄影是难以欣赏的&#xff0c;这是大部分人的共识。艺术作品的创作也自然具有较高的难度&#xff0c;很多时候画面的表达与思想不符。要么内容不足以反应思想&#xff0c;要么思想太浅&#xff0c;而内容太杂。想要真正理解作者要表达什么&#xff0c;就要从内容去逐个分解…

ZigBee案例笔记 -- 外部中断

文章目录1.中断概述2.中断屏蔽3.中断处理4.按键中断控制LED1.中断概述 CC2530有18个中断源&#xff0c;每个中断源都有它自己的位于一系列 SFR 寄存器中的中断请求标志。相应标志位请求的每个中断可以分别使能或禁用&#xff0c;中断分别组合为不同的、可以选择的优先级别&…

分布式ID之雪花算法

分布式ID常见生成策略 分布式ID生成策略常见的有如下几种: 数据库自增ID。UUID生成。Redis的原子自增方式。数据库水平拆分&#xff0c;设置初始值和相同的自增步长。批量申请自增ID。雪花算法。百度UidGenerator算法(基于雪花算法实现自定义时间戳)。美团Leaf算法(依赖于数据…

【ZooKeeper】第一章 快速入门

【ZooKeeper】第一章 快速入门 文章目录【ZooKeeper】第一章 快速入门一、概念二、安装1.环境准备2.安装3.配置二、命令操作1.数据模型2.服务端常用命令3.客户端常用命令一、概念 ZooKeeper 是 Apache Hadoop 项目下的一个子项目&#xff0c;是一个树形目录服务ZooKeeper 翻译…