一、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方法,显示在下面变量值: