spring源码分析

174 阅读7分钟

springmvc的启动过程

spring启动component-scan类扫描加载过程—源码分析 1、spring通过DispatcherServlet加载:

2、servlet的规范中,如果load-on-startup被设定了,那么就会被初始化的时候装载,而servlet装载时会调用其init()方法,那么自然是调用DispatcherServlet的init方法,

然后会调用一个refresh()方法,这个方法表面上是用来刷新的,其实也是用来做初始化bean用的

3、接下来需要知道的是如何初始化ApplicationContext的(按照使用习惯,其实只要得到了ApplicationContext,就得到了bean的信息,所以在初始化ApplicationCotext的时候,就已经初始化好了bean的信息,至少至少,它初始化好了bean的路径,以及描述信息),所以我们一旦知道ApplicationCotext是怎么初始化的,就基本知道bean是如何加载的了。

这里的XmlWebApplicationContext或则和ClassPathXmlApplicationContext都继承了类(间接继承),AbstractApplicationContext这个类中的refresh()方法是共用的,也就是他们都调用的这个方法来加载bean的,在这个方法中,通过obtainFreshBeanFactory方法来构造beanFactory的

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>

1、不要不略源码中的注释

2、不要一开始就死扣细节,先了解源码的脉络,熟悉细节

3、大胆猜测

4、根据方法的名字,了解知道是方法是什么

5、要坚持看源码

基础 反射

springioc

spring的启动???看马氏兵

springioc的生命周期: 1、先创建beanfactory工厂,对工厂初始化后,

2、beandefinition读取配置的文件,获取bean的定义信息

3、bean工厂的处理器,对bean定义的信息进行进一步的解析,比如${name},转换为值,或者重新设置bean的属性值

4、beanfactory实例化bean

5、populate方法对实例化的对象属性填充

6、之心aware接口需要执行的方法,获取其他的bean的属性

7、bean初始化的前置处理器

8、bean初始化

9、bean的后置处理器(springaop植入bean的位置)

10、bean创建完成

11、bean的销毁

ioc 解析配置文件,通过接口规范,实现方法

在使用时,通过反射实例化对象 对象的创建过程包括:实例化(内存开辟空间)--》对象填充属性set方法-->初始化(在创建对象前可以做的动作)-->创建对象

beanfactoryPostprocessor可以在创建bean前对bean的定义处理 在将bean的定义信息交由beanfactory前,有beanfactoryProatprocessor,用于提前处理解析的bean定义信息,如下图对数据库用户名称的读取

aware类的作用是方便bean对象获取容器中的bean属性 填充属性后,执行aware接口需要实现的方法

实例化创建完成beanpostp'rocessorbefore,和beanpostp'rocessorbefore,是创建对象前的操作

bean创建的过程 1、创建bean工场 refreshbeanfactory (如果有工场,就销毁,并创建新工厂)

2、loadbeandefinition方法读取配置文件,从而完成工厂的创建和bean配置文件的加载

3、invokBeanFactoryPostProcesor 调用各种bean处理器

4、registbeanpostprocessor 注册bean处理器 下面的这些注册工作都是为后来的实现准备

然后实例化对象

polulatbean填充bean的属性值

invokawaremethod方法,执行aware方法

为什么springaop的java实现,需要使用接口? 图为动态代理后,通过反射会生成代理类,代理类需要继承 invokhandler,从而执行父类的被代理方法, 因为实现了接口,生成的代理类可以实现,也就相当于静态代理的接口

也就是说,动态代理利用反射,生成的类似于静态代理的类(该类是目标方法的子类),这个类继承的invokhandler,可以调用父类的目标方法, 单继承 invokhandler,从而父类的目标方法可以通过反射执行 多实现接口,不同的类,通过继承的invokhandler的同时,实现了这个接口,在调用方法时,就可以调用代理后的方法

spring循环依赖

defaltsingaltone 三级缓存

@aspectj

springaop的原理: 如果没有主动设置参数或没有实现接口,就使用jdk的动态代理,否则使用cglib

他是在初始化bean对象后 在 后置处理器的applybeanpostprocessorafterinitalition内织入的 在bean的前置,如果没有使用接口,或者指定配置为true,就使用cglib代理 否则使用jdk jdk的动态代理使用的getproxy 的getproxynewinstance

spring容器的对象创建

对象创建的方法:1、new 2、反射3、创建设计模式

springmvc流程

前端控制器是一个servlet

流程说明: 1、客户端发送请求到dispatchservlet(前端控制器) 2、通过处理器映射器,根据url找到对应的handler,返回一个处理器的执行链(里面包括执行器,拦截器) 3、处理器执行器根据dispatchservlet所获取的执行链,去执行handler(处理器) 4、处理器将执行完成的最终结果封装成ModelAndView,返回给前端控制器(dispatchservlet) 5、前端控制器调用试图解析器(我们配置的),返回一个View对象给前端控制器(dispatchservlet) 6、前端控制器调用试图(HTML|Freemark),将解析的vew渲染到试图 7、试图响应回客户端

springboot主要做的事情是:1、内嵌了tomcat 2、实现了自动的装配。 springboot源码解析

webapplicationinnalization

spring@configration的实现原理:

因为在servlet3.0api的一个新规范:如果有类或者方法需要在容器启动的时候被调用,可以在项目的启动根目录下指定一个文件META-/services onstartup是javaconfig技术可以实现0配置 springboot指定了容器初始化的类,这个初始化的类里面有个onstartup方法,在执行时,会遍历执行所有实现了这个接口的类的startup方法,子类的startup方法只要启动了spring容器,将注册@configration注册进容器,同时通过传如的servletcxt,注册dispatcservlet,完成springmvc的整合

为什么web容器启动的时候,会调用spring开发的接口?

springboot需要实现这个接口,tomcat可以调用里面的onstartup方法

onstartup方法里面的annotationconfigwebapplicationcontext方法以注解的形式进入spring容器的入口classpathxmlapplicationcontext(初始话spring容器) 这个类可以注册配置类也就是有@configration注解的 如下图:

web容器会将servletcxt传如进来,通过创建dispatcservlet,并将其加入到servletcxt中,完成了springmvc的整合

@springbootapplication下面的注解 注解@autoconfigrationpackage:自动包扫描子目录的类 springboot的自动配置类的springfactory配置了所有的默认配置类 spring自动配置的核心:通过import注入autoconfigrationimportselector,importselector会扫描META-Spring。factories的配置文件(里面有所有的默认配置类),getAutoconfigration拿到所有自动配置的节点,getCandidateconfigrations根据扫描到的文件进行过滤,loadfactorynames去扫描配置文件里面所有自动配置类,在容器中初始化

springboot和其他项目的整合,需要导入以一个xxxx-starter的项目,

springboot如何内嵌web容器

springboot内置可tomcat、jetty和undertow三个容器

tomcat是springboot自动配置实现的

为什么springboot是一个java项目而不是web项目? 因为springboot使用了配置方法,不需要web.xml文件了 而tomcat是对指定的web项目,解析其web.xml文件

springmvc的底层是servlet技术,所以springmvc的dispatchserverlet是创建之后,存放在web容器中才可以使用 tomcate内有springmvc tomcat和spring,他们都是在jdk上面运行的,也可以说是依赖关系

tomcat注入到spring容器

springboot默认已经加了tomcat的依赖

下面是创建tomcat

spring boot的自动配置实在springioc容器初始化之后

springboot内嵌tomcat的使用,可以通过创建一个类,加上@configration去配置tomcat属性,也可以通过yml文件配置,在使用其他web容器,需要exclude掉内置的tomcat,然后引入starter包

springboot的run方法

main方法是为了接收命令行的参数,如Java -jar -xx.jar

netty源码

dubbo源码

zookepper源码