Spring源码(三)-Spring启动流程细节

一、spring的具体工作细节

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");

        debug运行后,F7进入new ClassPathXmlApplicationContext,首先是static代码块,此代码块是weblogic的一个bug,不用在意:

super(parent);

        super调用父类方法,源码中需要看父类代码,不要忽略,会初始化一些变量。

        super(parent) 父类调用过程:

                

                 AbstractApplicationContext类很重要,refresh方法在此类中

                

                 resourcePatternResolver ----- 用来解析xml等资源文件

                private String id = ObjectUtils.identittyToString(this); --- 上下文唯一标识    ------ createBeanFactory--

 当前容器的状态:

 锁:

Ant风格路径表达式表达式

 

 

 ResourceLoader接口--资源加载器

        AbstractXmlApplicationContext   --- validatiog --- xml文件的验证标志,默认为true

        Xml文件的格式规范要求:dtd/xsd             (dtd:document type definition 文档类型定义)

                (xsd  XML Schema Definition )

二、setConfigLocations(configLocations) 设置配置文件路径

         resolvePath() -- 路径处理---例如传入的文件名为:spring-${username}.xml

        new StandardEnvironment---调用父类构造方法,调用子类customizePropertySources()方法

springboot中StandardServletEnvironment继承StandardEnvironment类:

 mutable[ˈmjuːtəbl]  可变的 

private final MutablePropertySources propertySources = new MutablePropertySources();----加载一些属性资源

        

 placeholder 占位符  

 property resolver  属性解析器               resolver [rɪˈzɒlvə] 

createPlaceholderHelper  创建工厂类

raw [rɔː]未加工的;生的                   parse  [pɑːz] 作语法分析;

 spring-${abc${def}}.xml  --- 可以嵌套写占位符,解析方法中是递归调用解析

recursive  [rɪˈkɜːsɪv] 递归的     invocation [ˌɪnvəˈkeɪʃn] 调用     contain  [kənˈteɪn] 包含

                

 suffix  [ˈsʌfɪks] 后缀

indexOf返回字符串中第一个出现的指定子字符串,没有则返回-1

"abcdfvdsfdf".indexOf("df");   --- 返回3(第一个a是0)

"abcdfvdsfdf".indexOf("df", 4); ---- 从第4个位置(f)开始寻找,df出现的位置是 9 (第一个a是0)

StringUtils.substringMatch("abcdefghigklmn", 4, "e")  ---------  true

"abcdefg".substring(2,4) ---- cd   包2不包4

original  [əˈrɪdʒənl]起初的;原本的;           circular circular圆形的;   reference 参考

necessary  [ˈnesəsəri]必须的;必要的;   

"abcde".replace("a", "k")   ----  kbcde

"abcde".replace(1,3,"kk")  ----  akkde

AbstractRefreshableConfigApplicationContext.java   --- setConfigLocations() -- configLocations

三、 refresh()

     synchronized(this.startupShutdownMonitor)  -- 锁,刷新和销毁方法的监视器     

     (1)prepareRefresh() 容器刷新前的准备工作

            ① initPropertySources()  --- 在当前上下文的环境中初始化占位符资源----方法内是空的

        context  [ˈkɒntekst] 上下文;语境;环境

        initPropertySources()方法扩展-----自定义方法

        declare  [dɪˈkleə(r)] 声明;宣布   require 需要; resolve  [rɪˈzɒlv]解决;决定    

        stub  [stʌb] 存根;残存        actual instances 实例

     ClassPathXmlApplicationContext是AbstractApplicationContext子类

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext{
    public MyClassPathXmlApplicationContext(String... configLocations) {
        super(configLocations);
    }

    @Override
    protected void initPropertySources() {
        getEnvironment().setRequiredProperties("abc");
    }
}

MyClassPathXmlApplicationContext context = new MyClassPathXmlApplicationContext("applicationContext.xml");
//运行到refresh()方法中的initPropertySources(),会直接运行MyClassPathXmlApplicationContext 中方法

用实际实例替换任何存根属性源

        ②getEnvironment() 创建并获取当前对象

                missing 丢失的;错过      declare  [dɪˈkleə(r)]声明;宣布    

 图片中的异常意思为: 以下属性已按要求声明,但无法解析

此处添加属性:

 添加的属性放入requiredProperties进行验证,是否有对应值

         ③earlyApplicationListeners   刷新之前注册的本地监听器

                earlyApplicationEvents  多播器启动之前 发布的事件集合  

            以上两个默认是无对象的

 spring源码中 spplicationListeners是空的,springboot是有值的:

         (2) obtainFreshBeanFactory()       obtain [əbˈteɪn]  获得;赢得

        refreshBeanFactory()刷新bean工厂,原因是 启动当前容器之前可能已经启动好一个bean工厂了。    刷新之前,先把以前的bean工厂清空掉--destroyBeans  close

         beanFactory的allowCircularReferences默认true   ----  是否自动的解决循环依赖的问题    circular reference 循环依赖

        beanFactory的allowBeanDefinitionOverriding默认 true  --- overriding  [ˌəʊvəˈraɪd]  覆盖    允许bean的定义信息进行覆盖   

xml文件中<lookup-method></lookup-method>    <replaced-method></replaced-method>

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext{
    public MyClassPathXmlApplicationContext(String... configLocations) {
        super(configLocations);
    }
    
    @Override
    public void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        //此allowBeanDefinitionOverriding是AbstractRefreshiableApplicationContext类中的变量
        //此处也可直接写为beanFactory.setAllowBeanDefinitionOverriding(false);  就不用调用下面super.customizeBeanFactory()
        super.setAllowBeanDefinitionOverriding(false);
        super.setAllowCircularReferences(false);
        //如果不加super.customizeBeanFactory()调用,则启动时不会调用原方法
        super.customizeBeanFactory(beanFactory);
    }
}

    loadBeanDefinitions(beanFactory) 

                XmlBeanDefinitionReader beanDefinitionReader = new  XmlBeanDefinitionReader(beanFactory);  --- 适配器设计模式       

        capable 有能力的[ˈkeɪpəbl] 

        EntityResolver ---  sax(simple API for XML)xml的一种解析方式

EntiryResolver的注释:

 如果SAX应用程序需要实现对外部实体的定制处理,它必须实现该接口,并使用该方法向SAX驱动注册一个实例。

该external entiry 外部实体,是指xml中的标签对象

如果要解析xml文件,必须要知道xml的整体结构是什么样子,整体的结构在xsd或者dtd文件中放着,里面规范了接口的名字等信息

 一般情况下,xml文件中定义的地址是网络环境的东西,不联网的情况下,本地也存储了一些解析xml文件的工具文件:

 第一条:

可以根据此些文件,对xml文件进行读取和处理

EntityResolver ---  ResourceEntityResolver 实现了EntityResolver接口,读取本地的xsd、dtd文件,来完成相关的解析工作

pluggable [ˈplʌgəbl] 可插拔

 idea在debug模式下默认会调用类的toString方法,显示在下面变量值:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值