SpringBoot
入门案例解析
<packaging>jar</packaging>
为什么是 jar 不是 war?
SpringBoot默认的打包方式就是jar,内嵌tomcat
项目与Tomcat融为一体,部署,启动,运行一体化
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/>
</parent>
为什么用 parent?
<parent> maven中的继承标签
<dependencyManagement> 依赖管理标签
相当于说父亲帮我们管理依赖,我们需要声明才能使用
springboot是个很大的收集群, 收集了市面上常用的第三方依赖,
就不需要关心版本了
@SpringBootApplication做了什么?
包扫描
部署Tomcat
配置前端控制器
// 核心三注解
@ComponentScan
@SpringBootConfiguration
@EnableAutoConfiguration
注意:
1:一般贴有@SpringBootApplication的为启动类,一般放在根包下
2:一般springboot项目只有唯一一个启动类,启动类都是配置类
3:不管是spring定制的启动器,还是第三方定制的启动器,都需要编写
META-INF/spring.factories, 里面指定启动器的自动配置类
springboot提供了一堆的候选配置类.
- @ComponentScan: 开启组件扫描
- @SpringBootConfiguration: 作用等同于@Configuration注解,
- 也是用于标记配置类
- @EnableAutoConfiguration: 内部导入AutoConfigurationImportSelector,
- 该类中有个getCandidateConfigurations方法,
- 读取jar包中META-INF/spring.factories文件中配置类,
- 再根据条件进行加载和配置,
- 比如: AOP / PropertyPlaceholder / FreeMarker /
- HttpMessageConverter / Jackson / DataSource /
- DataSourceTransactionManager / DispatcherServlet / WebMvc 等等
springboot 自动配置原理(自动装配)
1.@ComponentScan
包扫描 扫描当前包及其子包
就不需要包扫描路径了
2.@SpringBootConfiguration
声明该类为配置类
就不需要 部署Tomcat 这个步骤
tomcat-embed 包 内嵌Tomcat 包
3.@EnableAutoConfiguration
导入了 自动配置选择器的类
boot-autoconfigure 包 最核心的包加载 spring.factories 中的 AutoConfiguration 中的 WebMVCAutoConfiguration 做了 配置前端控制器
@AutoConfigureAfter 意为指定类加载完之后,在加载本类
快速搭建springboot 项目
版本选择
添加依赖
项目结构
单元测试 Junit5
springboot 项目打包部署
添加打包插件 —>pom.xml
<!-- pom.xml中添加插件 -->
<build>
<plugins>
<!-- SpringBoot打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
拿到jar包给运维跑
运行
输入命令
java -jar sb-demo-1.0.0.jar
如果想要修改端口号
方法1:
方法2:
输入cmd 输入命令
java -jar sb-demo-1.0.0.jar --server.post=8888
SpringBoot优缺点
优点:
- 创建独立运行的Spring应用程序
- 嵌入的Tomcat,无需部署war文件
- 简化Maven配置
- 自动配置Spring
- 提供生产就绪型功能,如:日志,健康检查和外部配置等
- 不要求配置 XML
- 非常容易和第三方框架集成起来
缺点:
- 版本更新较快,可能出现较大变化
- 因为约定大于配置,所以经常会出现一些很难解决的问题
Banner更换()
热部署插件
<!-- SpringBoot热部署插件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
切换运行环境
多环境操作
SpringBoot参数配置
命令行参数优先级最高
参数配置一般在 application.properties 或者 YAML 配置
application.properties语法
server.port=80
server.session-timeout=30
server.tomcat.uri-encoding=UTF-8
spring.datasource.url = jdbc:mysql://localhost:3306/crm
spring.datasource.username = root
spring.datasource.password = admin
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
YAML语法 (官方推荐)
server:
port: 80
session-timeout: 30
tomcat.uri-encoding: UTF-8
spring:
datasource:
url : jdbc:mysql://localhost:3306/crm
username : root
password : admin
driverClassName : com.mysql.cj.jdbc.Driver
application.properties优先级
- 项目/config/application.properties
- 项目/application.properties
- classpath:config/application.properties
- classpath:application.properties
参数属性绑定
@ConfigurationProperties
/**
*配置属性批量获取注解
*从springboot配置文件: application.properties获取指定
*前缀的参数,
*然后按照参数(属性)名字注入对象中
*
*参数名必须一致
*/
@SpringBootApplication
public class App {
/**
* @ConfigurationProperties("jdbc")
* 配置属性批量获取注解
* 从springboot配置文件: application.properties获取指定
* 前缀的参数,
* 然后按照参数(属性)名字注入对象中
*
* 参数名必须一致
*/
@Bean
@ConfigurationProperties("jdbc")
public MyDataSource myDataSource(){
MyDataSource myDataSource = new MyDataSource();
return myDataSource;
}
}
数据库连接池
添加依赖 pom.xml
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
添加数据库四要素 ---->application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=admin
默认数据源- Hikari
Druid 集成
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
集成MyBatis
添加依赖
<!--mybatis集成到SpringBoot中的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
在application.properties 中加入日志扫描
#mybatis.configuration.lazy-loading-enabled=true
#mybatis.configuration.lazy-load-trigger-methods=clone
#mybatis.mapper-locations=classpath:cn/wolfcode/*/mapper/*Mapper.xml
#mybatis.type-aliases-package=cn.wolfcode.sb.domain
#打印SQL日志
logging.level.cn.wolfcode.crm.mapper=trace
加入@MapperScan(basePackages = “cn.scorpio.sb.mapper”)
在 启动类中加入
扫描 Mapper 包 (范围限定要小)
@SpringBootApplication
@MapperScan("cn.wolfcode.sb.mapper")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
配置事务
添加依赖
<!-- 支持使用 Spring AOP 和 AspectJ 进行切面编程。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
在 ServiceImpl 中 加入
@Transactional
@Transactional(readonly = true) // 只读操作
静态资源处理
如果在 static 中 添加一个 静态资源如 aaa.html 那么在 浏览器中可以直接访问 url: localhost/aaa.html
这是因为 springboot 做了映射 : 映射了 ip端口了 相等于 /
但是如果在 templates 中不可以直接访问
1. 默认情况下,Springboot会从classpath下的 /static,
/public , /resources , /META-INF/resources下加载静态资源
2. 可以在application.properties中
配置spring.resources.staticLocations属性来修改静态资源加载地址
3. 因为应用是打成jar包,所以之前的src/main/webapp就作废了,
如果有文件上传,那么就的必须去配置图片所在的路径
FreeMaker集成
要用 springboot 配置 FreeMaker 的配置类 和 视图解析器
添加 springboot 和 FreeMaker 的依赖
<!-- SpringBoot集成FreeMarker的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
但是在 springboot 2.2 之后 FreeMaker 的后缀改为了 .ftlh 但是如果 不想 改后缀 可以 在 application.properties 配置文件中 输入
spring.freemarker.suffix=.ftl
默认指定 templates 为 模板路径也不用写后缀
常见属性配置
spring.freemarker.enabled=true: 是否开启freemarker支持
spring.freemarker.charset=UTF-8: 模板编码
spring.freemarker.content-type=text/html: 模板contenttype
spring.freemarker.expose-session-attributes: 是否开启session属性暴露,默认false
spring.freemarker.prefix: 加载模板时候的前缀
spring.freemarker.settings.*: 直接配置freemarker参数
spring.freemarker.suffix: 模板文件后缀
spring.freemarker.template-loader-path=classpath:/templates/: 模板加载地址
#一般我们会做3个配置,其余默认即可
#暴露session对象的属性 能不能获取session
spring.freemarker.expose-session-attributes=true
#配置为传统模式,空值自动处理
spring.freemarker.settings.classic_compatible=true
#重新指定模板文件后缀 springboot 2.2.x 后 默认后缀为 .ftlh
spring.freemarker.suffix=.ftl
统一异常处理
框架自带 的 统一异常处理器 默认情况下 会把错误交给 BasicErrorController 类处理
需要在static 包 下创建一个 error 包 下面编写 404.html 和 5xx.html
404.html // 搜索不到
5xx.html // 5 开头的错误
@ControllerAdvice
@ControllerAdvice
请求进入请求映射方法之前,做功能增强, 典型应用: date类型参数格式化 , 拓展 springMVC date类型格式化有几种
请求进入请求映射方法之后,做功能增强, 典型应用: 统一异常处理
需要创建一个 advice 包 然后进行异常处理 创建一个 errorView.ftl 在templates 包下
@ExceptionHandler
@ExceptionHandler(?.class) 异常处理控制器注解
处理?类型异常
添加拦截器
在interceptor包中创建一个LoginInterceptor 类实现 handlerInterceptor
handlerInterceptor接口中有3个方法, 按照jdk8之前语法, 需要重写这3个方法,但是业务只需要实现一个即可, 碍于语法要求 不得不实现3个.其中两个是浪费 . 此时使用的方案: HandlerInterceptorAdapter /*空实现*/ handlerInterceptor , LoginInterceptor 类 继承 HandlerInterceptorAdapter 重写业务需要的哪个方法.
JDK 8 之后, 接口有默认实现功能, 天生就有了适配器功能, 所以就不需要适配器类了.
继承 HandlerInterceptorAdapter : JDK 8 之前的拦截器处理, 是一种设计模式 : 适配器设计模式 会浪费两个接口 后置拦截 和 中间拦截 , 只有前置拦截会起作用
实现 preHandle 类
定义好拦截器
配置拦截器 在 启动类中 实现 WebMvcConfigurer
重写 addInterceptors
// addPathPatterns("/**") 拦截所有
// excludePathPatterns("/static") 放行
参数对象.addInterceptor(loginInterceptor()).addPathPatterns("/**").excludePathPatterns("/static");
写个 LoginInterceptor 的 实例Bean
也可以不写 Bean 可以在 拦截类 上贴 @Component
综合案例
做一个员工的 crud 操作
分页插件
依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
创建query包
合理化分页
js / css 不需要 static , SpringBoot默认映射了
系统日志
工具的 System.out.println (不使用)
日志插件
SpringBoot默认开启日志打印
默认的日志格式为: 时间 日志级别 进程ID 线程名称 日志类 日志说明
日志级别
trace < debug < info < warn < error
项目刚上线 使用 trace
运行平稳了 使用 info
当跑了异常 使用 error
每个日志都有不同的级别 ,
SpringBoot日志配置 —> application.properties
#把日志级别修改为debug,不过我们一般不会更改,除非要调试找bug
,不然控制台显示的内容太多也容易乱
logging.level.root=trace
SpringBoot 默认 选择 Logback 作为日志框架
slf4j日志jar包
把日志语句 插入 需要打印的地方
private static final Logger log
= LoggerFactory.getLogger(当前类.class);
// 也可以使用 注解
@Slf4j
log.trace("日志打印-trace")
log.debug("日志打印-debug")
log.info("日志打印-info")
log.warn("日志打印-warn")
log.error("日志打印-error")
warn < error
项目刚上线 使用 trace
运行平稳了 使用 info
当跑了异常 使用 error