4、SpringBoot:JSR303数据校验及多环境切换
5、SpringBoot:自动配置原理
6、SpringBoot:自定义starter
7、SpringBoot整合JDBC
8、SpringBoot整合Druid
9、SpringBoot整合mybatis
10、SpringBoot:Web开发静态资源处理
11、SpringBoot:Thymeleaf模板引擎
12、SpringBoot:MVC自动配置原理
13、SpringBoot:页面国际化
14、SpringBoot:集成Swagger终极版
15、SpringBoot:异步、定时、邮件任务
16、SpringBoot:富文本编辑器
17、SpringBoot:Dubbo和Zookeeper集成
18、SpringBoot:集成SpringSecurity
SpringBoot简介
Spring是一个开源框架,2003年兴起的一个轻量级的Java开发框架,作者:RodJohnson。
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
****
为了降低Java开发的复杂性,Spring采用了以下4种关键策略:
1、基于POJO的轻量级和最小侵入性编程,所有东西都是bean;
2、通过IOC,依赖注入(DI)和面向接口实现松耦合;
4、通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;
学过javaweb的同学就知道,开发一个web应用,从最初开始接触Servlet结合Tomcat,跑出一个HelloWolrld程序,是要经历特别多的步骤;后来就用了框架Struts,再后来是SpringMVC,到了现在的SpringBoot,过一两年又会有其他web框架出现;你们有经历过框架不断的演进,然后自己开发项目所有的技术也在不断的变化、改造吗?建议都可以去经历一遍;
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景衍生一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
是的这就是Java企业级应用->J2EE->spring->springboot的过程。
随着Spring不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。SpringBoot正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用Spring、更容易的集成各种常用的中间件、开源软件;
SpringBoot基于Spring开发,SpirngBoot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。SpringBoot以约定大于配置的核心思想,默认帮我们进行了很多设置,多数SpringBoot应用只需要很少的Spring配置。同时它集成了大量常用的第三方库配置(例如Redis、MongoDB、Jpa、RabbitMQ、Quartz等等),SpringBoot应用中这些第三方库几乎可以零配置的开箱即用。
简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,springboot整合了所有的框架。
SpringBoot的主要优点:
真的很爽,我们快速去体验开发个接口的感觉吧!
Hello,World
我们将学习如何快速的创建一个SpringBoot应用,并且实现一个简单的Http请求处理。通过这个例子对SpringBoot有一个初步的了解,并体验其结构简单、开发快速的特性。
我的环境准备:
开发工具:
Spring官方提供了非常方便的工具让我们快速构建应用
项目创建方式一:使用SpringInitializr的Web页面创建项目
2、填写项目信息
3、点击”GenerateProject“按钮生成项目;下载此项目
4、解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。
5、如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。
项目创建方式二:使用IDEA直接创建项目
1、创建一个新项目
2、选择springinitalizr,可以看到默认就是去官网的快速构建工具那里实现
3、填写项目信息
4、选择初始化的组件(初学勾选Web即可)
5、填写项目路径
6、等待项目构建成功
项目结构分析:
通过上面步骤完成了基础项目的创建。就会自动生成以下文件。
1、程序的主启动类
2、一个application.properties配置文件
3、一个测试类
4、一个pom.xml
打开pom.xml,看看SpringBoot项目的依赖:
2、在包中新建一个HelloController类
@RestControllerpublicclassHelloController{@RequestMapping("/hello")publicStringhello(){return"HelloWorld";}}3、编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了Tomcat访问的端口号!
简单几步,就完成了一个web接口的开发,SpringBoot就是这么简单。所以我们常用它来建立我们的微服务项目!
如果遇到以上错误,可以配置打包时跳过项目运行测试用例
打成了jar包后,就可以在任何地方运行了!OK
彩蛋
如何更改启动时显示的字符拼成的字母,SpringBoot呢?也就是banner图案;
只需一步:到项目下的resources目录下新建一个banner.txt即可。
**SpringBoot这么简单的东西背后一定有故事,我们之后
我们之前写的HelloSpringBoot,到底是怎么运行的呢,Maven项目,我们一般从pom.xml文件探究起;
pom.xml
其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!
以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;
spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;
主启动类
分析完了pom.xml来看看这个启动类
//@SpringBootApplication来标注一个主程序类//说明这是一个SpringBoot应用@SpringBootApplicationpublicclassSpringbootApplication{publicstaticvoidmain(String[]args){//以为是启动了一个方法,没想到启动了一个服务SpringApplication.run(SpringbootApplication.class,args);}}但是一个简单的启动类并不简单!我们来分析一下这些注解都干了什么
作用:标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
进入这个注解:可以看到上面还有很多其他注解!
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters={@Filter(type=FilterType.CUSTOM,classes={TypeExcludeFilter.class}),@Filter(type=FilterType.CUSTOM,classes={AutoConfigurationExcludeFilter.class})})public@interfaceSpringBootApplication{//......}2.5、@ComponentScan这个注解在Spring中很重要,它对应XML配置中的元素。
作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义加载到IOC容器中
作用:SpringBoot的配置类,标注在某个类上,表示这是一个SpringBoot的配置类;
我们继续进去这个注解查看
//点进去得到下面的@Component@Configurationpublic@interfaceSpringBootConfiguration{}@Componentpublic@interfaceConfiguration{}这里的@Configuration,说明这是一个配置类,配置类就是对应Spring的xml配置文件;
里面的@Component这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
我们回到SpringBootApplication注解中继续看。
@EnableAutoConfiguration:开启自动配置功能
以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
点进注解接续查看:
@AutoConfigurationPackage:自动配置包
@Import({Registrar.class})public@interfaceAutoConfigurationPackage{}@import:Spring底层注解@import,给容器中导入一个组件
Registrar.class作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器;
这个分析完了,退到上一步,继续看
@Import({AutoConfigurationImportSelector.class}):给容器导入组件;
AutoConfigurationImportSelector:自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:
1、这个类中有一个这样的方法
//获得候选的配置protectedList
publicstaticList
我们根据源头打开spring.factories,看到了很多自动配置的文件;这就是自动配置根源所在!
WebMvcAutoConfiguration
我们在上面的自动配置类随便找一个打开看看,比如:WebMvcAutoConfiguration
可以看到这些一个个的都是JavaConfig配置类,而且都注入了一些Bean,可以找一些自己认识的类,看着熟悉一下!
所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中对应的org.springframework.boot.autoconfigure.包下的配置项,通过反射实例化为对应标注了@Configuration的JavaConfig形式的IOC容器配置类,然后将这些都汇总成为一个实例并加载到IOC容器中。
结论:
springboot所有自动配置都是在启动的时候扫描并加载:Spring.factories所有的自动配置类都在这里面,但不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功。
现在大家应该大概的了解了下,SpringBoot的运行原理,后面我们还会深化一次!
SpringApplication
我最初以为就是运行了一个main方法,没想到却开启了一个服务;
@SpringBootApplicationpublicclassSpringbootApplication{publicstaticvoidmain(String[]args){SpringApplication.run(SpringbootApplication.class,args);}}SpringApplication.run分析
分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
这个类主要做了以下四件事情:
1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用初始化器,设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类
查看构造器:
yaml语法学习
SpringBoot使用一个全局的配置文件,配置文件名称是固定的
配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
比如我们可以在配置文件中修改Tomcat默认启动的端口号!测试一下!
server.port=80813.2、yaml概述YAML是"YAMLAin'taMarkupLanguage"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML的意思其实是:"YetAnotherMarkupLanguage"(仍是一种标记语言)
这种语言以数据作为中心,而不是以标记语言为重点!
以前的配置文件,大多数都是使用xml来配置;比如一个简单的端口配置,我们来对比下yaml和xml
传统xml配置:
server:prot:80803.3、yaml基础语法说明:语法要求严格!
1、空格不能省略
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
字面量:普通的值[数字,布尔值,字符串]
字面量直接写在后面就可以,字符串默认不用加上双引号或者单引号;
k:v注意:
对象、Map(键值对)
#对象、Map格式k:v1:v2:在下一行来写对象的属性和值得关系,注意缩进;比如:
student:name:qinjiangage:3行内写法
student:{name:qinjiang,age:3}数组(List、set)
用-值表示数组中的一个元素,比如:
pets:-cat-dog-pig行内写法
pets:[cat,dog,pig]修改SpringBoot的默认端口号
配置文件中添加,端口号的参数,就可以切换端口;
server:port:8082注入配置文件
yaml文件更强大的地方在于,他可以给我们的实体类直接注入匹配值!
1、在springboot项目中的resources目录下新建一个文件application.yml
2、编写一个实体类Dog;
packagecom.kuang.springboot.pojo;@Component//注册bean到容器中publicclassDog{privateStringname;privateIntegerage;//有参无参构造、get、set方法、toString()方法}3、思考,我们原来是如何给bean注入属性值的!@Value,给狗狗类测试一下:
@Component//注册beanpublicclassDog{@Value("阿黄")privateStringname;@Value("18")privateIntegerage;}4、在SpringBoot的测试类下注入狗狗输出一下;
@SpringBootTestclassDemoApplicationTests{@Autowired//将狗狗自动注入进来Dogdog;@TestpublicvoidcontextLoads(){System.out.println(dog);//打印看下狗狗对象}}结果成功输出,@Value注入成功,这是我们原来的办法对吧。
5、我们在编写一个复杂一点的实体类:Person类
@Component//注册bean到容器中publicclassPerson{privateStringname;privateIntegerage;privateBooleanhappy;privateDatebirth;privateMap
person:name:qinjiangage:3happy:falsebirth:2000/01/01maps:{k1:v1,k2:v2}lists:-code-girl-musicdog:name:旺财age:17、我们刚才已经把person这个对象的所有值都写好了,我们现在来注入到我们的类中!
@SpringBootTestclassDemoApplicationTests{@AutowiredPersonperson;//将person自动注入进来@TestpublicvoidcontextLoads(){System.out.println(person);//打印person信息}}结果:所有值全部注入成功!
yaml配置注入到实体类完全OK!
课堂测试:
1、将配置文件的key值和属性的值设置为不一样,则结果输出为null,注入失败
2、在配置一个person2,然后将@ConfigurationProperties(prefix="person2")指向我们的person2;
@PropertySource:加载指定的配置文件;
@configurationProperties:默认从全局配置文件中获取值;
1、我们去在resources目录下新建一个person.properties文件
name=kuangshen2、然后在我们的代码中指定加载person.properties文件
@PropertySource(value="classpath:person.properties")@Component//注册beanpublicclassPerson{@Value("${name}")privateStringname;......}3、再次输出测试一下:指定配置文件绑定成功!
配置文件还可以编写占位符生成随机数
person:name:qinjiang${random.uuid}#随机uuidage:${random.int}#随机inthappy:falsebirth:2000/01/01maps:{k1:v1,k2:v2}lists:-code-girl-musicdog:name:${person.hello:other}_旺财age:13.7、回顾properties配置我们上面采用的yaml方法都是最简单的方式,开发中最常用的;也是springboot所推荐的!那我们来唠唠其他的实现方式,道理都是相同的;写还是那样写;配置文件除了yml还有我们之前常用的properties,我们没有讲,我们来唠唠!
【注意】properties配置文件在写中文的时候,会有乱码,我们需要去IDEA中设置编码格式为UTF-8;
settings-->FileEncodings中配置;
测试步骤:
1、新建一个实体类User
@Component//注册beanpublicclassUser{privateStringname;privateintage;privateStringsex;}2、编辑配置文件user.properties
user1.name=kuangshenuser1.age=18user1.sex=男3、我们在User类上使用@Value来进行注入!
@Component//注册bean@PropertySource(value="classpath:user.properties")publicclassUser{//直接使用@value@Value("${user.name}")//从配置文件中取值privateStringname;@Value("#{9*2}")//#{SPEL}Spring表达式privateintage;@Value("男")//字面量privateStringsex;}4、Springboot测试
user1.name=kuangshenuser1.age=18user1.sex=男结果正常输出:
@Value这个使用起来并不友好!我们需要为每个属性单独注解赋值,比较麻烦;我们来看个功能对比图
1、@ConfigurationProperties只需要写一次即可,@Value则需要每个字段都添加
2、松散绑定:这个什么意思呢比如我的yml中写的last-name,这个和lastName是一样的,-后面跟着的字母默认是大写的。这就是松散绑定。可以测试一下
3、JSR303数据校验,这个就是我们可以在字段是增加一层过滤器验证,可以保证数据的合法性
4、复杂类型封装,yml中可以封装对象,使用value就不支持
配置yml和配置properties都可以获取到值,强烈推荐yml;
如果我们在某个业务中,只需要获取配置文件中的某个值,可以使用一下@value;
如果说,我们专门编写了一个JavaBean来和配置文件进行一一映射,就直接@configurationProperties,不要犹豫!
JSR303数据校验
Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。我们这里来写个注解让我们的name只能支持Email格式;
使用数据校验,可以保证数据的正确性;
profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;
我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml,用来指定多个环境版本;
例如:
application-test.properties代表测试环境配置
application-dev.properties代表开发环境配置
但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;
我们需要通过一个配置来选择需要激活的环境:
#比如在配置文件中指定使用dev环境,我们可以通过设置不同的端口号进行测试;#我们启动SpringBoot,就可以看到已经切换到dev下的配置了;spring.profiles.active=dev4.4、yaml的多文档块和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件,更加方便了!
server:port:8081#选择要激活那个环境块spring:profiles:active:prod---server:port:8083spring:profiles:dev#配置环境的名称---server:port:8084spring:profiles:prod#配置环境的名称注意:如果yml和properties同时都配置了端口,并且没有激活其他环境,默认会使用properties配置文件的!
外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!
官方外部配置文件说明参考文档
springboot启动会扫描以下位置的application.properties或者application.yml文件作为Springboot的默认配置文件:
优先级1:项目路径下的config文件夹配置文件优先级2:项目路径下配置文件优先级3:资源路径下的config文件夹配置文件优先级4:资源路径下配置文件优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;
我们在最低级的配置文件中设置一个项目访问路径的配置来测试互补问题;
#配置项目的访问路径server.servlet.context-path=/kuang4.6、拓展,运维小技巧指定位置加载配置文件
我们还可以通过spring.config.location来改变默认的配置文件位置
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;这种情况,一般是后期运维做的多,相同配置,外部指定的配置文件优先级最高
自动配置原理
配置文件到底能写什么?怎么写?
SpringBoot官方文档中有大量的配置,我们无法全部记住
我们以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
这就是自动装配的原理!
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。
我们怎么知道哪些自动配置类生效?
我们可以通过启用debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;
#开启springboot的调试类debug=truePositivematches:(自动配置类启用的:正匹配)
Negativematches:(没有启动,没有匹配成功的自动配置类:负匹配)
Unconditionalclasses:(没有条件的类)
【演示:查看输出的日志】
掌握吸收理解原理,即可以不变应万变!
我们分析完毕了源码以及自动装配的过程,我们可以尝试自定义一个启动器来玩玩!
启动器模块是一个空jar文件,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库;
命名归约:
官方命名:
自定义命名:
1、在IDEA中新建一个空项目spring-boot-starter-diy
2、新建一个普通Maven模块:kuang-spring-boot-starter
3、新建一个Springboot模块:kuang-spring-boot-starter-autoconfigure
4、点击apply即可,基本结构
5、在我们的starter中导入autoconfigure的依赖!
7、我们编写一个自己的服务
packagecom.kuang;publicclassHelloService{HelloPropertieshelloProperties;publicHelloPropertiesgetHelloProperties(){returnhelloProperties;}publicvoidsetHelloProperties(HelloPropertieshelloProperties){this.helloProperties=helloProperties;}publicStringsayHello(Stringname){returnhelloProperties.getPrefix()+name+helloProperties.getSuffix();}}8、编写HelloProperties配置类
packagecom.kuang;importorg.springframework.boot.context.properties.ConfigurationProperties;//前缀kuang.hello@ConfigurationProperties(prefix="kuang.hello")publicclassHelloProperties{privateStringprefix;privateStringsuffix;publicStringgetPrefix(){returnprefix;}publicvoidsetPrefix(Stringprefix){this.prefix=prefix;}publicStringgetSuffix(){returnsuffix;}publicvoidsetSuffix(Stringsuffix){this.suffix=suffix;}}9、编写我们的自动配置类并注入bean,测试!
packagecom.kuang;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@Configuration@ConditionalOnWebApplication//web应用生效@EnableConfigurationProperties(HelloProperties.class)publicclassHelloServiceAutoConfiguration{@AutowiredHelloPropertieshelloProperties;@BeanpublicHelloServicehelloService(){HelloServiceservice=newHelloService();service.setHelloProperties(helloProperties);returnservice;}}10、在resources编写一个自己的META-INF\spring.factories
#AutoConfigureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.kuang.HelloServiceAutoConfiguration11、编写完成后,可以安装到maven仓库中!
1、新建一个SpringBoot项目
2、导入我们自己写的启动器
packagecom.kuang.controller;@RestControllerpublicclassHelloController{@AutowiredHelloServicehelloService;@RequestMapping("/hello")publicStringhello(){returnhelloService.sayHello("zxc");}}4、编写配置文件application.properties
kuang.hello.prefix="ppp"kuang.hello.suffix="sss"5、启动项目进行测试,结果成功!
对于数据访问层,无论是SQL(关系型数据库)还是NOSQL(非关系型数据库),SpringBoot底层都是采用SpringData的方式进行统一处理。
SpringBoot底层都是采用SpringData的方式进行统一处理各种数据库,SpringData也是Spring中与SpringBoot、SpringCloud等齐名的知名项目。
整合JDBC
1、我去新建一个项目测试:springboot-data-jdbc;引入相应的模块!基础模块
2、项目建好之后,发现自动帮我们导入了如下的启动器
spring:datasource:username:rootpassword:123456#serverTimezone=UTC解决时区的报错url:jdbc:mysql://localhost:3306/springbootserverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name:com.mysql.cj.jdbc.Driver4、配置完这一些东西后,我们就可以直接去使用了,因为SpringBoot已经默认帮我们进行了自动配置;去测试类测试一下
@SpringBootTestclassSpringbootDataJdbcApplicationTests{//DI注入数据源@AutowiredDataSourcedataSource;@TestpublicvoidcontextLoads()throwsSQLException{//看一下默认数据源System.out.println(dataSource.getClass());//获得连接Connectionconnection=dataSource.getConnection();System.out.println(connection);//关闭连接connection.close();}}结果:我们可以看到他默认给我们配置的数据源为:classcom.zaxxer.hikari.HikariDataSource,我们并没有手动配置
我们来全局搜索一下,找到数据源的所有自动配置都在:DataSourceAutoConfiguration文件:
@Import({Hikari.class,Tomcat.class,Dbcp2.class,Generic.class,DataSourceJmxConfiguration.class})protectedstaticclassPooledDataSourceConfiguration{protectedPooledDataSourceConfiguration(){}}这里导入的类都在DataSourceConfiguration配置类下,可以看出SpringBoot2.2.5默认使用HikariDataSource数据源,而以前版本,如SpringBoot1.5默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源;
HikariDataSource号称JavaWEB当前速度最快的数据源,相比于传统的C3P0、DBCP、Tomcatjdbc等连接池更加优秀;
可以使用spring.datasource.type指定自定义的数据源类型,值为要使用的连接池实现的完全限定名。
关于数据源我们并不做介绍,有了数据库连接,显然就可以CRUD操作数据库了。但是我们需要先了解一个对象JdbcTemplate
1、有了数据源(com.zaxxer.hikari.HikariDataSource),然后可以拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的JDBC语句来操作数据库;
2、即使不使用第三方第数据库操作框架,如MyBatis等,Spring本身也对原生的JDBC做了轻量级的封装,即JdbcTemplate。
3、数据库操作的所有CRUD方法都在JdbcTemplate中。
4、SpringBoot不仅提供了默认的数据源,同时默认已经配置好了JdbcTemplate放在了容器中,程序员只需自己注入即可使用
5、JdbcTemplate的自动配置是依赖org.springframework.boot.autoconfigure.jdbc包下的JdbcTemplateConfiguration类
JdbcTemplate主要提供以下几类方法:
编写一个Controller,注入jdbcTemplate,编写测试方法进行访问测试;
org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration数据源配置类作用:根据逻辑判断之后,添加数据源;
SpringBoot默认支持以下数据源:
com.zaxxer.hikari.HikariDataSource(SpringBoot2.0以上,默认使用此数据源)
org.apache.tomcat.jdbc.pool.DataSource
org.apache.commons.dbcp2.BasicDataSource
可以使用spring.datasource.type指定自定义的数据源类型,值为要使用的连接池实现的完全限定名。默认情况下,它是从类路径自动检测的。
@Configuration@ConditionalOnMissingBean({DataSource.class})@ConditionalOnProperty(name={"spring.datasource.type"})staticclassGeneric{Generic(){}@BeanpublicDataSourcedataSource(DataSourcePropertiesproperties){returnproperties.initializeDataSourceBuilder().build();}}8、SpringBoot整合Druid8.1、Druid简介Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。
Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了C3P0、DBCP等DB池的优点,同时加入了日志监控。
Druid可以很好的监控DB池连接和SQL的执行情况,天生就是针对监控而生的DB连接池。
Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
SpringBoot2.0以上默认使用Hikari数据源,可以说Hikari与Driud都是当前JavaWeb上最优秀的数据源,我们来重点介绍SpringBoot如何集成Druid数据源,如何实现数据库监控。
com.alibaba.druid.pool.DruidDataSource基本配置参数如下:
1、添加上Druid数据源依赖。
spring:datasource:username:rootpassword:123456url:jdbc:mysql://localhost:3306/springbootserverTimezone=UTC&useUnicode=true&characterEncoding=utf-8driver-class-name:com.mysql.cj.jdbc.Drivertype:com.alibaba.druid.pool.DruidDataSource#自定义数据源3、数据源切换之后,在测试类中注入DataSource,然后获取到它,输出一看便知是否成功切换;
packagecom.kuang.config;importcom.alibaba.druid.pool.DruidDataSource;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importjavax.sql.DataSource;@ConfigurationpublicclassDruidConfig{/*将自定义的Druid数据源添加到容器中,不再让SpringBoot自动创建绑定全局配置文件中的druid数据源属性到com.alibaba.druid.pool.DruidDataSource从而让它们生效@ConfigurationProperties(prefix="spring.datasource"):作用就是将全局配置文件中前缀为spring.datasource的属性值注入到com.alibaba.druid.pool.DruidDataSource的同名参数中*/@ConfigurationProperties(prefix="spring.datasource")@BeanpublicDataSourcedruidDataSource(){returnnewDruidDataSource();}}7、去测试类中测试一下;看是否成功!
@SpringBootTestclassSpringbootDataJdbcApplicationTests{//DI注入数据源@AutowiredDataSourcedataSource;@TestpublicvoidcontextLoads()throwsSQLException{//看一下默认数据源System.out.println(dataSource.getClass());//获得连接Connectionconnection=dataSource.getConnection();System.out.println(connection);DruidDataSourcedruidDataSource=(DruidDataSource)dataSource;System.out.println("druidDataSource数据源最大连接数:"+druidDataSource.getMaxActive());System.out.println("druidDataSource数据源初始化连接数:"+druidDataSource.getInitialSize());//关闭连接connection.close();}}输出结果:可见配置参数已经生效!
Druid数据源具有监控的功能,并提供了一个web界面方便用户查看,类似安装路由器时,人家也提供了一个默认的web页面。
进入之后
配置Druidweb监控filter过滤器
//配置Druid监控之web监控的filter//WebStatFilter:用于配置Web和Druid数据源之间的管理关联监控统计@BeanpublicFilterRegistrationBeanwebStatFilter(){FilterRegistrationBeanbean=newFilterRegistrationBean();bean.setFilter(newWebStatFilter());//exclusions:设置哪些请求进行过滤排除掉,从而不进行统计Map
spring.datasource.username=rootspring.datasource.password=123456spring.datasource.url=jdbc:mysql://localhost:3306/mybatisserverTimezone=UTC&useUnicode=true&characterEncoding=utf-8spring.datasource.driver-class-name=com.mysql.jdbc.Driver#指定myBatis的核心配置文件与Mapper映射文件mybatis.mapper-locations=classpath:mybatis/mapper/*.xml#注意:对应实体类的路径mybatis.type-aliases-package=com.kuang.mybatis.pojo已经说过springboot官方并没有提供myBaits的启动器,是myBatis官方提供的开发包来适配的springboot,从pom.xml文件中的依赖包名也能看出来,并非是以spring-boot开头的;
同理上面全局配置文件中的这两行配置也是以mybatis开头而非spring开头也充分说明这些都是myBatis官方提供的
可以从org.mybatis.spring.boot.autoconfigure.MybatisProperties中查看所有配置项
Mybatis整合包
mybatis-spring-boot-starter
1.导入包
2.配置文件
3.mybatis配置
4.编写sql
5.service层调用dao层
6.controller调用service层
好的,同学们,那么接下来呢,我们开始学习SpringBoot与Web开发,从这一章往后,就属于我们实战部分的内容了;
其实SpringBoot的东西用起来非常简单,因为SpringBoot最大的特点就是自动装配。
使用SpringBoot的步骤:
1、创建一个SpringBoot应用,选择我们需要的模块,SpringBoot就会默认将我们的需要的模块自动配置好
2、手动在配置文件中配置部分配置项目就可以运行起来了
3、专注编写业务代码,不需要考虑以前那样一大堆的配置了。
要熟悉掌握开发,之前学习的自动配置的原理一定要搞明白!
比如SpringBoot到底帮我们配置了什么?我们能不能修改?我们能修改哪些配置?我们能不能扩展?
没事就找找类,看看自动装配原理!
我们之后来进行一个单体项目的小项目测试,让大家能够快速上手开发!
静态资源处理
首先,我们搭建一个普通的SpringBoot项目,回顾一下HelloWorld程序!
写请求非常简单,那我们要引入我们前端资源,我们项目中有许多的静态资源,比如css,js等文件,这个SpringBoot怎么处理呢?
如果我们是一个web应用,我们的main下会有一个webapp,我们以前都是将所有的页面导在这里面的,对吧!但是我们现在的pom呢,打包方式是为jar的方式,那么这种方式SpringBoot能不能来给我们写页面呢?当然是可以的,但是SpringBoot对于静态资源放置的位置,是有规定的!
我们先来聊聊这个静态资源映射规则:
SpringBoot中,SpringMVC的web配置都在WebMvcAutoConfiguration这个配置类里面;
我们可以去看看WebMvcAutoConfigurationAdapter中有很多配置方法;
有一个方法:addResourceHandlers添加资源处理
Webjars本质就是以jar包的方式引入我们的静态资源,我们以前要导入一个静态资源文件,直接导入即可。
使用SpringBoot需要使用Webjars,我们可以去搜索一下:
要使用jQuery,我们只要要引入jQuery对应版本的pom依赖即可!
那我们项目中要是使用自己的静态资源该怎么导入呢?我们看下一行代码;
我们去找staticPathPattern发现第二种映射规则:/**,访问当前的项目任意资源,它会去找resourceProperties这个类,我们可以点进去看一下分析:
//进入方法publicString[]getStaticLocations(){returnthis.staticLocations;}//找到对应的值privateString[]staticLocations=CLASSPATH_RESOURCE_LOCATIONS;//找到路径privatestaticfinalString[]CLASSPATH_RESOURCE_LOCATIONS={"classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/"};ResourceProperties可以设置和我们静态资源有关的参数;这里面指向了它会去寻找资源的文件夹,即上面数组的内容。
所以得出结论,以下四个目录存放的静态资源可以被我们识别:
"classpath:/META-INF/resources/""classpath:/resources/""classpath:/static/""classpath:/public/"我们可以在resources根目录下新建对应的文件夹,都可以存放我们的静态文件;
我们也可以自己通过配置文件来指定一下,哪些文件夹是需要我们放静态资源文件的,在application.properties中配置;
spring.resources.static-locations=classpath:/coding/,classpath:/kuang/一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了!
首页处理
静态资源文件夹说完后,我们继续向下看源码!可以看到一个欢迎页的映射,就是我们的首页!
@BeanpublicWelcomePageHandlerMappingwelcomePageHandlerMapping(ApplicationContextapplicationContext,FormattingConversionServicemvcConversionService,ResourceUrlProvidermvcResourceUrlProvider){WelcomePageHandlerMappingwelcomePageHandlerMapping=newWelcomePageHandlerMapping(newTemplateAvailabilityProviders(applicationContext),applicationContext,getWelcomePage(),//getWelcomePage获得欢迎页this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService,mvcResourceUrlProvider));returnwelcomePageHandlerMapping;}点进去继续看
privateOptional
关于网站图标说明:
与其他静态资源一样,SpringBoot在配置的静态内容位置中查找favicon.ico。如果存在这样的文件,它将自动用作应用程序的favicon。
1、关闭SpringBoot默认图标
#关闭默认图标spring.mvc.favicon.enabled=false2、自己放一个图标在静态资源目录下,我放在public目录下
3、清除浏览器缓存!刷新网页,发现图标已经变成自己的了!
前端交给我们的页面,是html页面。如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。
jsp支持非常强大的功能,包括能写Java代码,但是呢,我们现在的这种情况,SpringBoot这个项目首先是以jar的方式,不是war,像第二,我们用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的。
那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢?
SpringBoot推荐你可以来使用模板引擎:
模板引擎,我们其实大家听到很多,其实jsp就是一个模板引擎,还有用的比较多的freemarker,包括SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,什么样一个思想呢我们来看一下这张图:
模板引擎的作用就是我们来写一个页面模板,比如有些值呢,是动态的,我们写一些表达式。而这些值,从哪来呢,就是我们在后台封装一些数据。然后把这个模板和这个数据交给我们模板引擎,模板引擎按照我们这个数据帮你把这表达式解析、填充到我们指定的位置,然后把这个数据最终生成一个我们想要的内容给我们写出去,这就是我们这个模板引擎,不管是jsp还是其他模板引擎,都是这个思想。只不过呢,就是说不同模板引擎之间,他们可能这个语法有点不一样。其他的我就不介绍了,我主要来介绍一下SpringBoot给我们推荐的Thymeleaf模板引擎,这模板引擎呢,是一个高级语言的模板引擎,他的这个语法更简单。而且呢,功能更强大。
我们呢,就来看一下这个模板引擎,那既然要看这个模板引擎。首先,我们来看SpringBoot里边怎么用。
怎么引入呢,对于springboot来说,什么事情不都是一个start的事情嘛,我们去在项目中引入一下。给大家三个网址:
Spring官方文档:找到我们对应的版本
找到对应的pom依赖:可以适当点进源码看下本来的包!
前面呢,我们已经引入了Thymeleaf,那这个要怎么使用呢?
我们首先得按照SpringBoot的自动配置原理看一下我们这个Thymeleaf的自动配置规则,在按照那个规则,我们进行使用。
我们去找一下Thymeleaf的自动配置类:ThymeleafPropert
@ConfigurationProperties(prefix="spring.thymeleaf")publicclassThymeleafProperties{privatestaticfinalCharsetDEFAULT_ENCODING;publicstaticfinalStringDEFAULT_PREFIX="classpath:/templates/";publicstaticfinalStringDEFAULT_SUFFIX=".html";privatebooleancheckTemplate=true;privatebooleancheckTemplateLocation=true;privateStringprefix="classpath:/templates/";privateStringsuffix=".html";privateStringmode="HTML";privateCharsetencoding;}我们可以在其中看到默认的前缀和后缀!
我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。
使用thymeleaf什么都不需要配置,只需要将他放在指定的文件夹下即可!
测试
1、编写一个TestController
@ControllerpublicclassTestController{@RequestMapping("/t1")publicStringtest1(){//classpath:/templates/test.htmlreturn"test";}}2、编写一个测试页面test.html放在templates目录下
测试页面