spring boot源码分析(一)
一、静态资源配置:
spring boot的静态资源配置有三种方式:
1.1、静态资源存放位置
在spring boot 种静态资源存放在位置有三种:
在WebMvcAutoConfiguration类下,有静态资源的默认配置
-
第一种:使用静态资源的依赖
在pom.xml文件种导入静态资源依赖后,会加载静态资源的jar包,jar包的webjars文件夹便是静态文件的存放位置
要为Webjars使用版本无关的URL,请添加
webjars-locator-core
依赖项。然后声明你的Webjar。以jQuery为例,添加"/webjars/jquery/jquery.min.js"
会产生"/webjars/jquery/x.y.z/jquery.min.js"
。其中x.y.z
是Webjar版本<dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator-core</artifactId> </dependency>
如果使用JBoss,则需要声明webjars-locator-jboss-vfs
依赖项而不是webjars-locator-core
。否则,所有Webjars都将解析为404
-
第二种:使用手动下载静态文件,静态文件的存放位置为:类路径下的 resources、static、public、meta-inf/resources文件夹(没有可手动创建)
优先级:resource > static > pubilc
在访问时,springboot 会默认在类路径的三个文件夹下寻找,路径不能加文件夹的名称,否则解析后会变成http://localhost:8080/static/static/vue.js资源将找不到
- 第三种:可在配置文件application.properties中手动配置:
如果不配置将找不到静态资源
1.2、首页配置及视图解析器
spring boot 默认配置了欢迎页
即将index.html文件放在静态资源文件夹下,访问localhost:8080即可返回欢迎页
但在实际开发中,首页需要返回后端数据,因此在配置首页时,是使用controller来返回欢迎页,需要thymeleaf模板解析器支持
controller处理的页面都必须放在templates文件夹下
二、spring mvc扩展
spring boot为我们提供了扩展接口:
****autoConfigurer 提供配置的扩展
****Customizer 提供配置的定制
spring boot 默认已经配置好了,许多组件(只要导入了组件的依赖),在spring boot 启动时,会自动加载autoconfigration.jar下的默认的自动配置类,自动配置类会自动加载pom.xml文件中导入的组件,完成自动配置
如果在开发中,spring boot 提供的配置功能不够用时,我们还可以编写自己的组件和自动配置类,对组件进行扩展
例对webMVC进行扩展,实现过滤器转发:
自定义自动配置类:
@Configuration注解的类为配置类
实现WebMvcConfigurer接口,便是webmvc的自定义配置类
@Bean注解的方法返回的对象,将自动加载进容器
在spring boot 启动时该配置类便会起作用将我的自定义的配置组件加入容器
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Bean
public HttpFilter myHttpFilter(){
return new MyCharacterEncodingFilter();
}
}
自定义配置:(实现请求过滤)
public class MyCharacterEncodingFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if(request.getServletPath().contains("login")) {
System.out.println(request.getServletPath().contains("login"));
response.sendRedirect("/");
return;
}
chain.doFilter(request,response);
}
}
也可配置其他组件
在dispatch中打断点调试(所有的请求都会走dodispatch这个方法)
可发现我们自定义的过滤器生效
三、错误页面定制
3.1、默认效果
默认情况下,如果是浏览器访问,请求发生错误(请求页面不存在时时),spring boot 会返回一个静态的错误视图
该视图中包含了状态码、错误发生时间等
如果是客户端访问将返回json数据
3.2、源码解析:
1.看看spring boot为我们配置了什么?
在自动配置包下,在spring boot 中提供了错误视图的自动配置类
2.ErrorViewResolver接口
该接口中只有一个方法,返回一个ModelAndView对象,与以往经验推测实现该接口的为错误页面的控制器
3.AbstractErrorController抽象类
AbstractErrorController继承了ErrorController接口
该接口只有一个方法,获取发生错误的路径
4、ErrorMvcAutoConfiguration
5、ErrorMvcAutoConfiguration自动配置类给容器中注入了以上4个组件
DefaultErrorAttributes 获取默认错误属性
ErrorPageCustomizer 错误页面定制器
BasicErrorController 错误控制器基类处理/error请求
6、ErrorPageCustomizer
系统出现错误,此类生效,来到/error请求
7.BasicErrorController
错误控制器基类处理/error请求
看到BasicErrorController继承了AbstractErrorController类,所以我们分析BasicErrorController类即可
BasicErrorController类是一个控制器,处理的请求路径是 /error
该类中有两个非常重要的方法
7.1(一):如果是浏览器的请求将返回错误的html页面
resolveErrorView方法:(AbstractErrorController类的方法)
ErrorViewResolver的resolver.resolveErrorView方法返回modelandvoew,否则返回null
所以去哪个页面由ErrorViewResolver决定,即DefaultErrorViewResolver
7.2、DefaultErrorViewResolver类
7.2.1、该类在静态代码块中初始化了一个Map数据
该map中封装了状态码的第一个字符即
- 400、401等以4开头 -----> 4 --------->4xx
- 500、501等以5开头 ----->5 --------->5xx
7.2.2、 该类重写了resolveErrorView方法
7.2.3、resolve方法生成modelandview
7.2.4、DefaultErrorAttributes类得到请求的错误属性
7.2.5、以上都没有配置
即以上都返回null, 则会返回一个name为error的视图
在ErrorMvcAutoConfiguration配置类提供了静态的WhitelabelErrorViewConfiguration的自动配置类
该类中有一个StaticView的静态内部类但只有容器中有error的bean时才会生效生成error的视图对象
根据HttpServletRequest request 获取请求信息,拼接到buffer的字符串当中,写入response中
即:
(二):如果是客户端则返回json数据
如果是其他客户端访问,由该方法接受处理直接返回json数据
(三)返回定制返回的数据:
由前面我们了解到:spring boot请求在发生异常时,请求会走错误处理机制,在此机制,做了两大事情,一个返回错误页面或json数据,一个获取错误信息;
要定制返回数据,比先了解spring boot 获取处理信息的原理
由源码可知,spring boot底层是通过getErrorAttibutes()方法获取错误信息,该方法属于BasicErrorController,所以我们可以重写该类的getErrorAttibutes方法和我们的异常类
异常类:(当发生错误时,抛出该异常)
在条件不满足时,抛出异常
此时运行程序会抛出异常并返回一下数据
如果是浏览器将该数据渲染为系统生成的错误页面(作者转向我们的自定义错误页面,我们自己去渲染错误页面的样式)
如果是其他客户端则返回该json字符串
思路:我们要定制该数据,就要编写两个类,对中间结果进行处理,即在异常发生后,转往/error请求时对异常进行处理,再对getErrorAttibutes进行重写
MyExceptionHendler
自定义异常处理类
MyErrorAttr类重写getErrorAttributes方法
至此,错误页面以及数据定制及源码分析完毕
运行项目:再postman中观察返回数据
注意:spring boot框架默认,发生异常时,获取不到自定义异常的异常类信息,需要在配置文件中配置
四、servlet配置:
spring boot为我们默认提供了嵌入式的servlet容器自动配置
1.1、ServletWebServerFactoryAutoConfiguration
servletweb服务工厂自动配置类
此类中为我们提供了ServletWebServerFactoryConfiguration自动配置类
1.2、ServletWebServerFactoryConfiguration配置类
此类中为我们注入了Tomcat\Jetty\Undertow的工厂
Tomcat
Jetty
Undertow
只是没有导入Jetty\Undertow依赖,Jetty\Undertow没有生效
在工厂中创建了服务器(Tomcat)
1.3、替换spring boot中嵌入式servlet容器
步骤:根据源码可知
-
只要在pom.xml中提出原来的服务器依赖,导入所选要的服务器即可
-
spring boot的mvc依赖,默认提供了Tomcat依赖
-
剔除Tomcat依赖,在mvc中剔除即可
-
导入所需要的服务器依赖
1.4、servlet容器的配置
1.4.1、默认配置
以Tomcat为例:
Tomcat源码中,提供了默认配置
1.4.2、修改配置:
方式一:
在配置文件中配置(略)
方式二:
结论:重写对应的定制器customize方法即可
运行结果:
五、三大组件注册
web的三大组件,spring boot为我们提供了三大组件的注册类(不使用也是可以的,如之前的过滤器的注册,直接实现响应的结构,在mvc的自定义配置类中注入到spring容器中也是可以的)
类别 | 注册组件 |
---|---|
拦截器 | FilterRegistrationBean |
过滤器 | InterceptorRegistrationBean |
servlet | ServletRegistrationBean |
以servlet注册为例说明:
编写自定义servlet
使用ServletRegistrationBean注册
六、数据源配置:
我们分析spring boot的DataResource自动配置类,来进行数据源的配置
数据源配置需要数据库的支持
6.1、导入数据库依赖
在自动配置包下有个jdbc包这里封装了对数据源的配置
观察jdbc包,下面类的以及其作用
在配置文件中对数据源进行配置
spring boot默认提供的数据源,在配置类中对数据源的类型进行了(全类名)指明,否则不会生效
测试类
运行结果:
发现springboot默认提供的数据源是Hikari,传说目前最快的数据库
6.2、源码分析
6.2.1进入数据源自动配置类
观察如果容器中没有数据源,则该配置类生效,该类中有一个数据源连接池配置类
观察该配置类默认会导入这5中数据源
自动导入了静态Hikari类,该类在数据源配置类中
6.2.2进入数据源配置类
进一步观察
在注入Hikari时,配置了数据源类型
在此创建了数据源,并进行了绑定
6.3、数据源替换
6.3.1、我们以druid为例,探索数据源的切换配置
druid是Alibaba开源的数据库连接池,功能强大
由于数据源属性和配置文件绑定,在配置文件中配置即可
测试结果
6.3.2、配置属性绑定
由于druid是外部引入的数据库,所以要手动绑定druid与配置文件
未绑定时,druid的配置,无法在配置文件中配置
此时,这些配置就会生效
6.4、druid后台监控配置
druid提供了后台监控功能,对数据源的所有操作均能够监控,并提供了,可视的web页面