01SpringBoot复习笔记
SpringBoot复习笔记
一.springBoot 基础
1.工程结构解析
1.mvn/wrapper: mvn版本切换(并非mvn官方提供,第三方工具,springboot工程给我们装好了,可以直接用)
spring-boot中引入mvn/wrapper mvnw… 解决maven版本与插件配合不好的问题
(一般mvn插件都是基于某个版本的,所以会导致mvn版本较高时,使用以前的插件在高版本下没法用,所以需要重新安装低版本mvn,需要切换
mvn-wrapper可以完成mvn版本的切换,实际工作中用到的地方不多。可以忽略)
2..gitignore:git忽略信息
3.01-primary.iml:idea中用到的关于该工程的一些信息
4..md:记笔记,文档
5.src:
java:
@SpringBootApplication (组合注解,springboot 启动类)//启动类本身就是一个javaConfig,可以充当Spring 的配置文件
@configuration(java 配置类)
resource:web应用的根路径
static:
template:
application.properties:springboot配置文件(配置一些基本信息,数据库连接,端口号,redis连接等)
target:编译之后的文件存储路径
2.pom文件解析
jar包与jar.origianl 的关系?
jar 中包含依赖可以直接通过 java -jar 运行(部署) 会把启动需要(springBoot)以及自己的东西(自己的代码)编译进去
jar.original,不包含依赖,只有自己写的内容(给别的项目用)
jar包中的 必须包含 (MANIFEST.MF) 文件,且该文件中有Main-class jar包才能启动,springboot 还要有Start-Class,否则jar包会启动失败
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ttkgaOI-1633607590241)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210817224001452.png)]
打包后出现jar 和 jar.orginal 的原因
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pucUI35G-1633607590241)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210817224447225.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CBDG26zD-1633607590242)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210817224541502.png)]
spring-boot-maven-plugin 依赖了父工程,父工程做了一次repackage,生成时名字结尾也是jar,repackage时把老的jar后面加了orginal
版本号依赖了父版本,可以properties中更改父版本中的某一个jar版本号,来改变自己依赖的版本号
3.创建基于war的工程
springboot 打成jar包 内置tomcat,放到哪都可以直接运行,但是有些时候我们需要一个war包,不需要内置的tomcat来启动它。
package com.review;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
} //启动类下面会多一个ServletInitializer类
// 配置应用程序。通常您需要做的就是添加源(例如配置类),因为其他设置具有合理的默认值。您可以选择(例如)添加默认命令行参数,或设置活动的 Spring 配置文件
1.相较于普通springboot工程添加ServletInitializer类初始化类
2.pom文件添加spring-boot-starter-tomcat(并添加只在编译测试时生效,打成war之后不需要tomcat了)。packaging改为war,如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQkb32yb-1633607590242)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210817231120360.png)]
4.yml文件解析
问题1:yml中不提示(如下图解决即可)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vat6Nhv4-1633607590243)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210817232735043.png)]
yml中是嵌套式的方式,要求空格,我们一般用两个空格
properties的优先级高于yml
5.Actuator监控器
**Actuator**是springboot提供的一个可插拔模块,用于对工程进行监控。通过不同的监控终端实现不同的监控功能。可以部署到每个工程中实现对每一个工程的监控。
部署指的是依赖导入,启动时会有actuator ,expersing 指默认暴露的终端数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vmMXO9o2-1633607590243)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818000809299.png)]
server:
port: 8083
servlet:
context-path: /uus #上下文路径
#设置actuator info信息 (随便写)
info:
company:
name: review
url: http://www.review.com
address: China
author:
name: daiguojun
department: 研发部
#从pom文件中读取信息,要与标签对应
project:
grouopid: @[email protected]
artifactid: @[email protected]
management:
endpoints:
web:
exposure:
# include: ["health","info"] #开启某个终端
include: "*" # * 在yaml 文件属于关键字,所以需要加引号,开启所有终端
exclude:
- env
- health #两种写法
# exclude: ["env","info"] #指定要关闭的监控终端
# base-path: /base #修改actuator默认访问路径(actuator)
# server:
# port: 8084 #指定actuator监听的端口
监控终端在springcloud学习上会用到监控终端。
终端简介:
mappings:查看当前工程中所有的uri与处理器的映射关系,以及详解的处理器方法及其映射规则。
beans:查看当前应用中所有的对象信息
env:查看当前应用程序运行主机的所有软硬件环境信息
二、SpringBoot应用
1.自定义异常页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vOj1OWed-1633607590244)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818184008467.png)]
public.error 下添加404 500即可
2.一个工程启动多个进程(idea)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NatTcxew-1633607590244)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818185811808.png)]
选中允许并行,以-D开头,后面跟yml配置文件中的属性即可实现一个工程启动多个进程
3.多配制式多环境选择实现
(1)相同的代码运行在不同的开发环中,定义多个配置文件,在application.yml中**
spring:
profiles:
active: test
(2)不同的环境执行不同的实现类(实现类上加@Profile("")注解) 强大
@Service("SomeService")
@Profile("dev")
public class SomeServiceImpl implements SomeService {
@Override
public String hello() {
return "调用开发环境hello()实现";
}
}
@Service("SomeService")
@Profile("test")
public class OtherSomeServiceImpl implements SomeService {
@Override
public String hello() {
return "调用测试环境hello()实现";
}
}
运行方式实现:jar包启动时后面跟环境选择配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IhVaDJlO-1633607590244)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818193634184.png)]
4.单配置式多环境选择实现
spring:
profiles:
active: test
---
server:
port: 8084
servlet:
context-path: /uus
spring:
profiles: dev
---
server:
port: 8084
servlet:
context-path: /uus
spring:
profiles: test
5.自定义配置文件的读取
@Value("${server.port}")
private String port;
读取配置文件值 赋值 给对象
6.springboot中使用jsp
(1)webapp 下指定资源目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tQji2lm9-1633607590245)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818215640418.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wDzvkTrO-1633607590246)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210818215659879.png)]
(2)添加依赖
<!-- 用于解析jsp页面-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
RestController不能解析视图
7.整合mybatis
(1)依赖导入
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
(2)yml中添加相关配置
#数据库连接相关
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot_demo?serverTimezone=GMT%2B8&characterEncoding=utf-8
username: root
password: root
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 10
maximum-pool-size: 30
auto-commit: true
idle-timeout: 30000
pool-name: HikariCP
max-lifetime: 900000
connection-timeout: 10000
connection-test-query: SELECT 1
session:
store-type: redis
timeout: 1800
redis:
host: 127.0.0.1
port: 6379
devtools:
restart:
enabled: false
mybatis:
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:/mapper/*.xml,classpath*:com/review/**.xml
# 注册别名
type-aliases-package: com.review.entity
configuration:
#配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
map-underscore-to-camel-case: true
# mybatis缓存配置
cache-enabled: false
#配置JdbcTypeForNull, oracle数据库必须配置
jdbc-type-for-nu
8.springboot对事物的支持
@Transactional(rollbackFor = Exception.class)
9.springboot对日志的控制
springboot 中使用的日志技术为logback。其与Log4j都出自同一人,性能要优于Log4j。
(logback.xml对日志的输出控制,控制台打印info日志,把报错信息以及debug信息分别写到error.log和debug.log中)
10.springboot 整合SSRM
redis mybatis
Redis 数据分类:
使用redis缓存的数据可以划分为两类:
1.DB更新后,redis缓存中的数据马上清楚,以保证将来缓存中的数据与DB中数据的绝对一致性。(使用注解的方式)
2.对数据准确性要求不是高,只要与DB中的数据差别不大,就可以。这类数据一般会设置过期时效 (自定义设置缓存时间)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GQfELbj-1633607590247)(C:\Users\daiguojun\AppData\Roaming\Typora\typora-user-images\image-20210821190454367.png)]
redis 高并发情况下存在哪些问题:
1.缓存穿透:针对查询结果为空的情况,当从数据库查询结果为空时,有可能会出现缓存穿透的情况
**解决方案:**为这些为null的结果赋默认值
2.缓存雪崩:当缓存中的某些缓存在同一很短的时段内几乎同时到期,此时就可能会引发缓存雪崩的问题。
**解决方案:**提前规划好系统中所有缓存的到期时间。
3.热点缓存: 缓存雪崩中的特例,当某一个缓存的有效期到达时其可能会引发热点缓存(并发)
**解决方案:**双重检测锁机制,
//redis 高并发情况下存在可能会存在哪些问题 (热点缓存,双重检测锁的实现,解决高并发下多请求都访问数据库造成热点缓存的问题)
@Override
public Integer getStudentCount() {
BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps(STUDENT_INFO);
//从redis 中获取指定key的value
Object count = ops.get();
//双重检测
if(count == null){
//同步代码块只能执行一个请求,其他请求进入到阻塞队列(2,3,4)
synchronized (this){
//d第一个请求进if,其余都不进
count = ops.get();
if (count == null){
//查数据库
count = studentDao.getStudengsCount();
//将查询结果存放到reids并指定过期时间
ops.set(count,1,TimeUnit.MINUTES);
}
}
}
return (Integer)count;
}
11.双重检测锁的线程安全问题
代码中涉及到双重检测锁需要考虑线程安全的问题
package com.review.util;
import com.review.entity.Student;
import org.springframework.stereotype.Component;
/**
* @author daiguojun
* @date 2021-07-13 22:29
* 双重检测锁线程安全问题
* 解决方案:
* 1.将方法变成同步放发,只能有一个线程执行(效率不高,降低吞吐量)synchronized
* 2.在存在线程安全的成员变量声明前,添加 volatile(保证new对象的三部不会变)
* 3.若存在线程安全的成员变量为Integer Long Boolean 可以将他们定义为 AtomicXxx类型(AtomicLong。。线程安全的)
*/
@Component
public class StudentFactory {
private volatile Student student;
public synchronized Student getInstance(){
if(student == null){
synchronized (this){
if(student == null){
//new 对象 三部
//1.申请堆空间,2.将对象的数据初始化到堆空间中,3.将student引用指向到堆空间
// 数据量大的情况下,先进行第三部,数据没有初始化到堆空间,就可能会出现返回结果为null的情况
student = new Student("1","1","1");
}
}
}
return student;
}
}
上一篇: Ubuntu 20.04使用Firefox缺少Flash的解决方案
下一篇: 接口与抽象类