天天看点

Springboot

springboot

spring是一个开源框架,2003 年兴起的一个轻量级的java 开发框架,作者:rod johnson

为了降低java开发的复杂性,spring采用了以下4种关键策略:

基于pojo的轻量级和最小侵入性编程,所有东西都是bean;

通过ioc,依赖注入(di)和面向接口实现松耦合;

基于切面(aop)和惯例进行声明式编程;

通过切面和模版减少样式代码,redistemplate,xxxtemplate;

spring boot 基于 spring 开发,spirng boot 本身并不提供 spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 spring 框架的应用程序。也就是说,它并不是用来替代 spring 的解决方案,而是和 spring 框架紧密结合用于提升 spring 开发者体验的工具。spring boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 spring boot 应用只需要很少的 spring 配置。同时它集成了大量常用的第三方库配置(例如 redis、mongodb、jpa、rabbitmq、quartz 等等),spring boot 应用中这些第三方库几乎可以零配置的开箱即用。

为所有spring开发者更快的入门

开箱即用,提供各种默认配置来简化项目配置

内嵌式容器简化web项目

没有冗余代码生成和xml配置的要求

环境:

java version "1.8.0_181"

maven-3.6.1

springboot 2.5

工具:

idea

步骤:

点击create new project

Springboot
Springboot
Springboot
Springboot
Springboot
Springboot
Springboot

yaml是 "yaml ain't a markup language" (yaml不是一种标记语言)的递归缩写。在开发的这种语言时,yaml 的意思其实是:"yet another markup language"(仍是一种标记语言)

这种语言以数据作为中心,而不是以标记语言为重点!

传统xml配置:

yaml配置:

springboot使用一个全局的配置文件 , 配置文件名称是固定的

application.properties

语法结构 :key=value

application.yml

语法结构 :key:空格 value

配置文件的作用 :修改springboot自动配置的默认值,因为springboot在底层都给我们自动配置好了;

语法要求严格!

空格不能省略

以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。

属性和值的大小写都是十分敏感的。

字面量直接写在后面就可以 , 字符串默认不用加上双引号或者单引号;

注意:

“ ” 双引号,不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思;

比如 :name: "xiaozhi \n hello"

输出 :xiaozhi 换行 hello

'' 单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出

比如 :name: ‘xiaozhi \n hello’

输出 :xiaozhi \n hello

格式:

如 写法一

写法二

用 - 值表示数组中的一个元素

行内写法

在springboot项目中的resources目录下新建一个文件 application.yml

编写一个实体类 dog;

编写一个复杂一点的实体类:person 类

@configurationproperties(prefix = "person")添加该注解idea会下面提示

Springboot

需要在pom.xml中加入

测试类

功能

@configurationproperties

@value

松散绑定(松散语法)

支持

不支持

spel

jsr303数据校验

复杂类型封装

@configurationproperties只需要写一次即可 , @value则需要每个字段都添加

松散绑定:这个什么意思呢? 比如我的yml中写的last-name,这个和lastname是一样的, - 后面跟着的字母默认是大写的。这就是松散绑定。

jsr303数据校验 , 这个就是我们可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

复杂类型封装,yml中可以封装对象 , 使用value就不支持

springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。

profile是spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;

需要激活才能使用

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!

外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!

Springboot

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为spring boot的默认配置文件:

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

springboot会从这四个位置全部加载主配置文件;互补配置;

一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!

一但这个配置类生效;这个配置类就会给容器中添加各种组件;

这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

所有在配置文件中能配置的属性都是在xxxxproperties类中封装着;

配置文件能配置什么就可以参照某个功能对应的这个属性类

springboot启动会加载大量的自动配置类

我们看我们需要的功能有没有在springboot默认写好的自动配置类当中;

我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxautoconfigurartion:自动配置类;给容器中添加组件

xxxxproperties:封装配置文件中相关属性;

了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

@conditional派生注解(spring注解版原生的@conditional作用)

作用:必须是@conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

创建项目

Springboot

创建文件application.yaml

有了数据源(com.zaxxer.hikari.hikaridatasource),然后可以拿到数据库连接(java.sql.connection),有了连接,就可以使用原生的 jdbc 语句来操作数据库;

即使不使用第三方第数据库操作框架,如 mybatis等,spring 本身也对原生的jdbc 做了轻量级的封装,即jdbctemplate。

数据库操作的所有 crud 方法都在 jdbctemplate 中。

spring boot 不仅提供了默认的数据源,同时默认已经配置好了 jdbctemplate 放在了容器中,程序员只需自己注入即可使用

jdbctemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 jdbctemplateconfiguration 类

execute方法:可以用于执行任何sql语句,一般用于执行ddl语句;

update方法及batchupdate方法:update方法用于执行新增、修改、删除等语句;batchupdate方法用于执行批处理相关语句;

query方法及queryforxxx方法:用于执行查询相关语句;

call方法:用于执行存储过程、函数相关语句。

创建jdbccontroller

java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。

druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 c3p0、dbcp 等 db 池的优点,同时加入了日志监控。

druid 可以很好的监控 db 池连接和 sql 的执行情况,天生就是针对监控而生的 db 连接池。

druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

spring boot 2.0 以上默认使用 hikari 数据源,可以说 hikari 与 driud 都是当前 java web 上最优秀的数据源,我们来重点介绍 spring boot 如何集成 druid 数据源,如何实现数据库监控。

github地址:https://github.com/alibaba/druid/

配置

缺省值

说明

name

配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:"datasource-" + system.identityhashcode(this)

jdbcurl

连接数据库的url,不同数据库不一样。例如: mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto

username

连接数据库的用户名

password

连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用configfilter。详细看这里:https://github.com/alibaba/druid/wiki/使用configfilter

driverclassname

根据url自动识别

这一项可配可不配,如果不配置druid会根据url自动识别dbtype,然后选择相应的driverclassname(建议配置下)

initialsize

初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getconnection时

maxactive

8

最大连接池数量

maxidle

已经不再使用,配置了也没效果

minidle

最小连接池数量

maxwait

获取连接时最大等待时间,单位毫秒。配置了maxwait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useunfairlock属性为true使用非公平锁。

poolpreparedstatements

false

是否缓存preparedstatement,也就是pscache。pscache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。

maxopenpreparedstatements

-1

要启用pscache,必须配置大于0,当大于0时,poolpreparedstatements自动触发修改为true。在druid中,不会存在oracle下pscache占用内存过多的问题,可以把这个数值配置大一些,比如说100

validationquery

用来检测连接是否有效的sql,要求是一个查询语句。如果validationquery为null,testonborrow、testonreturn、testwhileidle都不会其作用。

testonborrow

true

申请连接时执行validationquery检测连接是否有效,做了这个配置会降低性能。

testonreturn

归还连接时执行validationquery检测连接是否有效,做了这个配置会降低性能

testwhileidle

建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timebetweenevictionrunsmillis,执行validationquery检测连接是否有效。

timebetweenevictionrunsmillis

有两个含义: 1) destroy线程会检测连接的间隔时间2) testwhileidle的判断依据,详细看testwhileidle属性的说明

numtestsperevictionrun

不再使用,一个druiddatasource只支持一个evictionrun

minevictableidletimemillis

connectioninitsqls

物理连接初始化的时候执行的sql

exceptionsorter

根据dbtype自动识别

当数据库抛出一些不可恢复的异常时,抛弃连接

filters

属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall

proxyfilters

类型是list<com.alibaba.druid.filter.filter>,如果同时配置了filters和proxyfilters,是组合关系,并非替换关系

log4j.properties

Springboot
Springboot

webjars本质就是以jar包的方式引入我们的静态资源 , 我们以前要导入一个静态资源文件,直接导入即可。

要使用jquery,我们只要要引入jquery对应版本的pom依赖即可!

访问:只要是静态资源,springboot就会去对应的路径寻找资源,我们这里访问:http://localhost:8080/webjars/jquery/3.4.1/jquery.js

四个目录存放的静态资源

Springboot

可以将index.html放到public、templates

templates下的话需要cotroller

springboot2.0版本之前可以修改 放到public下

环境配置

2.0之后直接放到public或static下即可

配置内容

扩展使用springmvc 官方文档如下:

if you want to keep spring boot mvc features and you want to add additional mvc configuration (interceptors, formatters, view controllers, and other features), you can add your own @configuration class of type webmvcconfigurer but without @enablewebmvc. if you wish to provide custom instances of requestmappinghandlermapping, requestmappinghandleradapter, or exceptionhandlerexceptionresolver, you can declare a webmvcregistrationsadapter instance to provide such components.

我们要做的就是编写一个@configuration注解类,并且类型要为webmvcconfigurer,还不能标注@enablewebmvc注解;我们去自己写一个;我们新建一个包叫config,写一个类mymvcconfig;

全面接管即:springboot对springmvc的自动配置不需要了,所有都是我们自己去配置!

springmvc自动配置都失效了!回归到了最初的样子

环境springboot,thymeleaf,spring web,mysql driver,jdbc api

在项目文件夹下创建config,创建springmvcconfig.java(扩展springmvc)

Springboot

resources资源文件下新建一个i18n目录,存放国际化配置文件

login.properties文件,还有一个login_zh_cn.properties;idea自动识别

Springboot
Springboot
Springboot
Springboot
Springboot
Springboot
Springboot

login.properties :默认

英文:

中文:

springboot配置文件( properties )

springboot配置文件(yaml)

在templates里创建文件夹error,在error文件下放404.html即可

异步处理还是非常常用的,比如我们在网站上发送邮件,后台会去发送邮件,此时前台会造成响应不动,直到邮件发送完毕,响应才会成功,所以我们一般会采用多线程的方式去处理这些任务。

启动类也需要加上注解

邮件发送,在我们的日常开发中,也非常的多,springboot也帮我们做了支持

邮件发送需要引入spring-boot-start-mail

springboot 自动配置mailsenderautoconfiguration

定义mailproperties内容,配置在application.yml中

自动装配javamailsender

测试邮件发送

Springboot

项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候,分析一次前一天的日志信息,spring为我们提供了异步执行任务调度的方式,提供了两个接口

taskexecutor接口

taskscheduler接口

两个注解:

@enablescheduling

@scheduled

(1) seconds minutes hours dayofmonth month dayofweek year(秒 分钟 小时 日 月 星期 年)

(2)seconds minutes hours dayofmonth month dayofweek(秒 分钟 小时 日 月 星期)

字段

允许值

允许的特殊字符

秒(seconds)

0~59的整数

, - * / 四个字符

分(minutes)

小时(hours)

0~23的整数

日期(dayofmonth)

1~31的整数(但是你需要考虑你月的天数)

,- * ? / l w c 八个字符

月份(month)

1~12的整数或者 jan-dec

星期(dayofweek)

1~7的整数或者 sun-sat (1=sun)

, - * ? / l c # 八个字符

年(可选,留空)(year)

1970~2099

  每一个域都使用数字,但还可以出现如下特殊字符,它们的含义是:

  (1)*:表示匹配该域的任意值。假如在minutes域使用*, 即表示每分钟都会触发事件。

  (2)?:只能用在dayofmonth和dayofweek两个域。它也匹配域的任意值,但实际不会。因为dayofmonth和dayofweek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用,如果使用表示不管星期几都会触发,实际上并不是这样。

  (3)-:表示范围。例如在minutes域使用5-20,表示从5分到20分钟每分钟触发一次

  (4)/:表示起始时间开始触发,然后每隔固定时间触发一次。例如在minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.

  (5),:表示列出枚举值。例如:在minutes域使用5,20,则意味着在5和20分每分钟触发一次。

  (6)l:表示最后,只能出现在dayofweek和dayofmonth域。如果在dayofweek域使用5l,意味着在最后的一个星期四触发。

  (7)w:表示有效工作日(周一到周五),只能出现在dayofmonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 dayofmonth使用5w,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,w的最近寻找不会跨过月份 。

  (8)lw:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。

  (9)#:用于确定每个月第几个星期几,只能出现在dayofmonth域。例如在4#2,表示某月的第二个星期三。

  (1)0 0 2 1 * ? * 表示在每月的1日的凌晨2点调整任务

  (2)0 15 10 ? * mon-fri 表示周一到周五每天上午10:15执行作业

  (3)0 15 10 ? 6l 2002-2006 表示2002-2006年的每个月的最后一个星期五上午10:15执行作

  (4)0 0 10,14,16 * * ? 每天上午10点,下午2点,4点

  (5)0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时

  (6)0 0 12 ? * wed 表示每个星期三中午12点

  (7)0 0 12 * * ? 每天中午12点触发

  (8)0 15 10 ? * * 每天上午10:15触发

  (9)0 15 10 * * ? 每天上午10:15触发

  (10)0 15 10 * * ? * 每天上午10:15触发

  (11)0 15 10 * * ? 2005 2005年的每天上午10:15触发

  (12)0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发

  (13)0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发

  (14)0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发

  (15)0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发

  (16)0 10,44 14 ? 3 wed 每年三月的星期三的下午2:10和2:44触发

  (17)0 15 10 ? * mon-fri 周一至周五的上午10:15触发

  (18)0 15 10 15 * ? 每月15日上午10:15触发

  (19)0 15 10 l * ? 每月最后一日的上午10:15触发

  (20)0 15 10 ? * 6l 每月的最后一个星期五上午10:15触发

  (21)0 15 10 ? * 6l 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发

  (22)0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发

</string,></string,></com.alibaba.druid.filter.filter></map<string,></map<string,></string,></string,></string,></string,object>