欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

01SpringBoot复习笔记

程序员文章站 2022-07-12 15:39:05
...

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;
    }
}