一:spring基础
spring工作的大体流程:1.加载配置文件或者注解配置->解析配置文件或注解配置->根据解析好的配置创建没有属性的对象,也就是通过反射来实现初始化->给属性赋值也是通过反射->从容器获取spring对象然后使用->最后销毁容器
创建对象的方法:1.new 对象 2.子类继承父类,在父类new对象 3.反射,最重要也是常用的方法 4.,之前我们介绍的设计模式,工厂模式,工厂方法,抽象工厂都可以创建对象
解析配置文件xml,注解->解析好的结果封装到BeanDefinitionReader中->反射生成无属性的对象芳容ioc容器中。这里有个扩展点,也就是随着spring的发展,今后可能会解析json配置文件或注解然后封装到BeanDefinitonReader。
spring底层是如何解析带$的配置呢?比如数据源动态url. 通过bfpp,beanfactorypostprocessor.
spring实例化和初始化的区别:
1.实例化是指在堆中申请一小块空间然后new对象,属性都是默认值。
2.初始化是指给属性赋值后还有其他的步骤,比如初始化init后置方法,执行aware接口,执行bpp方法
刚刚说的$的解析就是在这个BeanFactoryPostProcessor里面完成的,这里面有很多扩展点,比如完成beandefinition的修改。完成$的赋值操作,还有解析自定义的class注解
aware接口:
spring 初始化的流程
Aop实现的两种方式:
这就是我们之前说的设计模式里面的监听器模式。spring中有很多设计模式,后续我遇到会一一分析,包括maybatis里面的核心实现代理模式。
二:循环依赖
核心实现原理:实例化和初始化分开,提前暴露对象
三级缓存:
实例化的时候有个getEarlyBeanReference lambda表达式表示是否需要创建代理对象
当前的对象是否正在创建?如果是的话代表正在循环依赖放入三级缓存后会把isCurrentCreate置为true,会放入二级缓存earlySingletonObject
运行时bean引用
Lambda表达式去调用createBean
三:spring启动流程分析
注意: 变量可以嵌套
就这样环境变量初始化结束,包括环境变量的替换,递归遍历等操作。
四:Fefresh核心代码
第一部分:刷新容器
子类继承父类,重写了父类的接口那么使用子类初始化的时候就会调用子类重写的方法,从而实现了自定义的方法,这也是多态提现。
校验必输属性
第二部分:创建工厂
上面那个参数表示是否可以循环依赖,true表示可以循环依赖,还有一个beandefinition覆盖的参数。
修改循环依赖的初始值以及beandefinition重写的初始值
重写父类方法然后super修改父类的成员变量
不允许循环依赖,不允许覆盖beandefiniton信息
忽略这些Aware接口进行自动注入。
五:spring配置文件加载流程
判断文件是dtd还是xsd
加载文档对象,根据输入流解析xml文件
具体的解析过程
指定配置属性
这个属于设计模式中的模板方法。这个方法很重要。
解析spring标签和自定义标签
解析具体的标签
解析bean
具体的解析流程是非复杂,也就是用jdk自带的xml解析工具来解析各种配置文件中的标签,包括系统自带的标签和自定义标签,解析好后放入beandefinitionmap中,这个beandefinitionmap的key为beanname,value为beandefinition,当我们需要使用的时候就根据beanname来获取到具体的beandefinition.
五:aop源码解读
这里的解析过程有个重要的设计模式:责任链模式,把解析到的around,before,after,afterreturning根据顺序放入责任链中。后续使用的时候有个拓扑排序,也就是使用的时候,around和before的顺序 不确定。单一定在after前面。
aop用作事物,在之前 的某一个框架中我就遇到过事物不生效,后续根据分析源代码发现多数据源导致事物不生效,也就是说多数据源导致session不是同一个,所以事物不生效。自己的session管理自己的数据源,大家如果在配置多数据源的时候要注意这个事物失效的情况。
这个配置非常关键:也就是可以取代我们自定义配置 文件的解析,全部解析注解,这也就是0配置化的核心实现类。
六:springboot源码解析
这行代码就是sprinigboot的和核心,自动装配的原理,约定大于配置的编程习惯,解析/meta-inf/spring.factories里面的配置文件,然后注入到spring容器里,要用的时候直接拿出来,这也就是我们在pom.xml里面新增一个依赖就可以使用的核心原理
跟tomcat整合的核心代码。