笔记给分享给看看

野先生

前端知识

框架

  1. javaSE:韩顺平900.

  2. javaWeb:尚硅谷最新版JavaWeb全套教程,javaweb零基础入门完整版_哔哩哔哩_bilibili

  3. Lambda:尚硅谷Java入门视频教程,宋红康java基础视频_哔哩哔哩_bilibili

  4. 动态代理:jdk动态代理,cglib动态代理,代理设计模式,aop切面编程_哔哩哔哩_bilibili

  5. Spring:【尚硅谷】Spring框架视频教程(spring超详细源码级讲解)_哔哩哔哩_bilibili

  6. Spring:黑马程序员新版Spring零基础入门到精通,一套搞定spring全套视频教程(含实战源码)_哔哩哔哩_bilibili

  7. SpringMVC:【尚硅谷】SpringMVC教程丨一套快速上手spring mvc_哔哩哔哩_bilibili

  8. MyBatis:尚硅谷MyBatis实战教程全套完整版(初学者零基础从入门到精通,好评如潮,资料齐全)_哔哩哔哩_bilibili

  9. MyBatisPlus:尚硅谷MyBatisPlus教程(mybatis-plus框架精讲)_哔哩哔哩_bilibili

  10. Maven:黑马程序员Maven全套教程,maven项目管理从基础到高级,Java项目开发必会管理工具maven_哔哩哔哩_bilibili

  11. SpringBoot2:【尚硅谷】SpringBoot2零基础入门教程(spring boot2干货满满)_哔哩哔哩_bilibili

  12. SpringSecurity:尚硅谷SpringSecurity框架教程(spring security源码剖析从入门到精通)_哔哩哔哩_bilibili

  13. GIT:尚硅谷Git入门到精通全套教程(涵盖GitHub\Gitee码云\GitLab)_哔哩哔哩_bilibili

  14. Mysql:黑马程序员 MySQL数据库入门到精通,从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili

  15. Linux: 【小白入门 通俗易懂】2021韩顺平 一周学会Linux_哔哩哔哩_bilibili

  16. Redis:黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目_哔哩哔哩_bilibili

  17. 消息队列:Kafka、ActiveMQ、TubeMQ、RocketMQ

  18. RabbitMQ :尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq_哔哩哔哩_bilibili

  19. Nginx:尚硅谷Nginx教程由浅入深(一套打通丨初学者也可掌握)_哔哩哔哩_bilibili

  20. Netty:尚硅谷Netty视频教程(B站超火,好评如潮)_哔哩哔哩_bilibili

  21. 微服务。

  22. 容器Docker。

  23. K8S

  24. CI/CD

常用类库

JAVASE

最基础

JDK

JDK介绍
  1. JDK编程环境

  2. JRE运行环境

  3. JVM运行软件

JDK目录介绍
  1. JRE运行环境

  2. bin目录是开发工具

  3. lib依赖包

  4. src源码

  5. db是jdk自带数据库

  6. include是C和C++开发JDK所用的头文件

  7. demo例子

配置JAVA_HOME

方便DOS命令调用lib中的命令【命令对应:命令 -help】

项目结构
  1. 项目

  2. 类等

  3. 字段等

命名

  1. 规则

    1. 字母,数字,下划线,美元符为元素

    2. 不能是关键字

    3. 不能是数字开头

  2. 规范

    1. 包名全小写

    2. 类名,接口名大驼峰

    3. 变量名,方法名小驼峰

    4. 常量名,全大写下划线连接

变量
  1. 使用

    1. 声明

    2. 赋值

  2. 四类八种

    1. 整数Long要使用L

    2. 浮点数Folat要使用F,是近似值

    3. 字符输出Unicod编码

    4. 布尔只能是两种值

加号
  1. 左右是数值是加法

  2. 左右有字符串是拼接

编码
  1. ASCII统一一个字节

  2. Unicode统一两个字节【java的字符编码】

  3. UTF-8字母一个字节,汉字三个字节

  4. GBK字母一个字节汉字两个字节

  5. gb2312可以表示汉字

  6. big5可繁体中文

类型转换
  1. 不同类型之间的计算

  2. 两条自动转换线

  3. 整数到浮点数转换中只有int到double不会丢失精度

  4. 【非自动转换就是强转,会丢失精度或溢出】

String

转成字符串

  1. 字符串相加拼接成字符

转成基本类型

  1. Integer.parseInt()解析成Int

  2. 字符从字符串下标获取就行

  3. 解析成基本类型必须保证类型正确

运算
运算符
  1. 单目:+,-,*,/,%

  2. 双目:++,--

  3. 三目:boolean ? value1 : value2

  4. 关系:==,!=,<,>,<=,>=,instanceof

  5. 逻辑:&&,&,||,|,!,^

  6. 赋值:=,单目=

进制
  1. 二进制

  2. 八进制

  3. 十进制

  4. 十六进制F

位运算

正数三码合一,负数

  1. 源码

  2. 反码:源码保留符号位其他全部取反

  3. 补码:反码加一

位运算

  1. <<左移

  2. <<右移

  3. >>>无符号右移

  4. ~取反

  5. &与

  6. |或

  7. ^异或

流程

  1. 顺序:向前引用

  2. 分支:if...else。switch...case...default【break防止穿透】。

  3. 循环:for。while。do...while。

  4. break:跳出循环

  5. continue:跳出本次循环

  6. return:跳出方法

数组

该数据类型解决单个数据存放问题,多个相同数据方便使用。

特点

  1. 定长

  2. 连续下标

  3. 存储相同元素

使用

  1. 声明

  2. 开辟空间

  3. 初始化

  4. 下标取元素

内存

内存布局

  1. 方法区:类加载信息

  2. 栈:执行方法

  3. 堆:存放对象

  4. 常量池:存放字符串,或final常量

类加载时机

  1. new本类

  2. new子类

  3. 使用类的静态成员

  4. 反射

继承的所有属性都在一个对象中。

类加载过程

解决字节码加载到内存开始,到Class类对象创建

  1. 加载:加载字节码到内存【方法区】【并且创建类对象】

  2. 连接

    1. 验证:验证内存中的字节码【格式,数据,字节码,符号引用】

    2. 准备:静态变量默认初始化

    3. 解析:常量池中的符号引用替换成直接引用

  3. 初始化:开始静态初始化

【-Xverify:none:关闭大部分验证】

对象创建

  1. 类加载过程【先加载父类对象】

    1. 静态属性默认初始化

    2. 静态属性显示初始化:属性直接初始化和静态代码块初始化按照顺序来。

  2. 实例化对象【先加载父类对象】

    1. 属性初始化

    2. 属性显示初始化:属性直接初始化和代码块初始化按照顺序来。

    3. 构造方法初始化

  3. 赋值给引用

  4. 指定初始化

静态属性存储。说法一:静态属性在方法区的静态域。说法二:静态属性是创建的class对象中。

面向对象-基础

  1. 属性

  2. 方法

  3. 构造函数

  4. 封装

  5. 继承

  6. 多态

  7. 静态

  8. 代码块

该数据类型解决数组问题,有类型,有名称,可以使用函数。

解决类型的定义。

  1. 属性

  2. 方法

  3. 构造器

  4. 代码块

  5. 内部类

使用

  1. 实例化

  2. 初始化

  3. 对象操作属性和方法

属性

类数据类型中的元素。

特点

  1. 有访问修饰符

  2. 有默认值

方法

解决执行代码可重用问题。

特点

  1. 有访问修饰符

  2. 有返回值

  3. 有方法名

  4. 有参数

返回值
  1. 方法声明返回值可以是任意类型或void

  2. return返回具体返回值或跳出方法

参数
  1. 可以有,可以没有

  2. 调用的时候传参兼容【兼容,个数,顺序】

  3. 【传参机制】

方法递归

解决同源的复杂问题,将大问题一步步拆分成为一个最简单的问题。

方法自己调用自己

方法重载

解决功能和名称映射问题,同功能的方法名称保持一致。

  1. 方法名相同

  2. 形参列表不一致【类型,个数,顺序】

可变参数

解决不确定参数个数的问题,将任意个同类型参数的方法封装成一个方法。

  1. 可变参必须放在形参列表最后

  2. 可变参只能出现一个

  3. 传参可以是数组也可以是多个同类型参数

作用域

解决数据的生命,节省存储数据的空间

  1. 全局变量:

    1. 普通属性作用域是对象,静态属性作用域是类。

    2. 有访问修饰符

    3. 有默认值

    4. 生命等同对象

  2. 局部变量:

    1. 所在代码块中

    2. 生命等同方法

  3. 全局变量和局部变量可以同名

构造器

解决对象实例化问题,同时有参构造还可以初始化。

  1. 有访问修饰符

  2. 没有返回值

  3. 构造器方法名等同于类名

  4. 没有任意一个构造器的时候会给一个无参构造

  5. 构造器由JVM系统调用

  6. 构造器可以重载

This

解决本类属性和参数同名时,指向本类属性。

  1. 本质this指向本对象

  2. 指属性

  3. 指方法

  4. 指构造

面向对象-中级

解决相同类名的问题,管理类。

  1. package表示所在包

  2. import表示引入的包或类

  3. 使用引入两个同名类的时候,需要权限的类名指定

  4. 命名规则:com+公司名+项目名+业务模块

访问修饰符

解决方法和属性的访问权限问题。

  1. public公开

  2. protected受保护,同类同包或子类

  3. default同类同包

  4. private本类

封装

解决类中的属性设置和获取时加上一层过滤。

  1. 将属性和操作属性的方法封装在一起

  2. 操作属性的时候加一层过滤

使用

  1. 属性私有化

  2. 设置和获取方法

构造器参与封装

解决创建对象的时候没有一层过滤

  1. 构造器初始化时调用对应set方法

继承

解决重复定义类的问题。

  1. 访问修饰符决定属性和方法继承或不继承

  2. 子类必须调用父类的构造器,完成父类初始化.

  3. 所有子类默认调用父类无参构造器

  4. 显示调用父类构造器要放在子类构造器的第一行代码

  5. this和super都只能放在构造器第一行代码,不能共存

  6. 所有类都是Object的子类

  7. 一个类只能有一个父类

  8. 所有类都可以调用Object类的方法

  9. 继承需要保持IS-A的关系

查找机制

  1. 从子类向Object去找

  2. 找到不可以访问的就会报错

Super

解决继承中子类访问父类的对象信息。

  1. 父类可访问属性

  2. 父类可访问方法

  3. 父类可访问构造

  4. 【表示父类对象】

重写

解决继承中,子类覆盖父类的方法。

  1. 方法名相同

  2. 形参列表相同

  3. 访问权限比父类大

  4. 返回值比范围父类小

多态

解决不确定具体类型,用统一类型表示具体类型。

方法多态

解决相同的方法名,调用出来不同的功能实现。

  1. 方法重载:根据不同的参数决定

  2. 方法重载:对象不一样就调用不一样的方法

对象多态
  1. 对象引用类型不能修改,也就是编译类型不能修改

  2. 父类引用可以指向子类对象

向上转型

解决父类引用类型指向子类运行类型。

  1. 父类引用指向子类实现

  2. 只能访问父类的属性和方法

  3. 以及子类的重写方法

向下转型

解决父类类型不能调用子类特有方法。

  1. 子类引用强制指向父类引用【类型强制转换】

  2. 编译类型和运行类型一致,就等同于创建一个子类

多态使用
  1. 多态数组

  2. 多态参数

动态绑定机制

解决继承中所有的方法查找,从实现类开始查找。

  1. 方法有动态绑定,从具体实现开始查找方法实现。

  2. 属性没有动态绑定,从引用类型开始查找。

Object

解决所有类的父类,提供最基础的方法。

  1. equals比较对象地址【==还可以判断基本类型的值】常重写判断内容

  2. getClass运行时类型

  3. finalize回收没有引用的对象时调用该方法【System.gc主动回收】

  4. hashCode对象hash值【集合处重写】

  5. toString对象字符串表示【全类名+@+hash十六进制值】常重写打印内容【输出对象默认调用】

断点调试

解决代码运行类型源码查看,看代码原理或排错。

  1. F7跳入

  2. F8跳过

  3. F9下一个断点

  4. shift+F7强制跳入

  5. shift+F8跳出

面向对象-高级

Static

解决类所持有的属性,方法

  1. 修饰属性:是类变量,可以和访问修饰符顺序颠倒

  2. 修饰方法:是类方法,可以和访问修饰符顺序颠倒

类变量

解决所有同类对象的共同属性。

  1. 对象名和类名都可以调用

  2. 所有同类对象共享属性

  3. 【静态属性和属性的区别只有对象共享的区别】

类方法

解决不创建对象直接调用方法。

  1. 对象名和类名都可以调用

  2. 【静态方法和普通方法的区别静态方法只能调用静态成员】

Main方法

解决JVM调用方法的入口。

  1. public:虚拟机不总是和main方法同包

  2. static:虚拟机调用main方法不必创建对象

  3. void:虚拟机在获取返回值的时候程序就结束了

  4. main:虚拟机默认找到的入口方法标签

  5. args:虚拟机执行main方法所需要的命令

  6. IDEA参数传递:program arguments

代码块

解决类,对象初始化问题

  1. 静态代码块:给静态属性赋值,或者

  2. 普通代码块:抽取构造器的前面公共代码

单例模式

解决全局只有一个该类的对象。

  1. 饿汉式:创建好一个实例给静态属性,等待使用静态方法去获取

  2. 懒汉式:第一次使用静态方法获取实例的时候才创建对象

各自特点

  1. 加载时机:饿汉式类加载的时候就创建,懒汉式调用方法的时候才创建。

  2. 线程安全:饿汉式是线程安全的,懒汉式线程不安全。

  3. 资源问题:饿汉式可能会一次都没有使用,懒汉式不会有资源浪费问题。

final

解决类,方法,属性,局部变量的使用限制。

  1. 类:不能被继承

  2. 方法:不能被重写

  3. 属性:只能初始化一次【常量】

  4. 局部变量:只能赋值一次

构造器不能被final修饰,构造器本就不能被继承。

final类一定全是final方法,final方法的类不一定是final类。

final配合static:类不会被加载【没有顺序要求】

抽象类

解决继承中,父类的方法只给方法定义不给实现的抽象方法。

  1. 抽象类只能被继承不能被实例化。

  2. 抽线方法只能被重写。

抽象方法一定在抽象类中,但是抽象类中不一定有抽象方法。

只有实现类实现了抽线类的所有抽象方法,才能实例化。

接口

解决实现类的规范。

定义

  1. 接口只能是public或者default。和类的访问修饰符一样

  2. 所有的属性都是静态常量。【public默认】

  3. 所有方法都是抽象方法。【public默认】

  4. 接口是LIKE-A的关系

实现

  1. 实现类实现接口,必须实现所有的抽象方法。

  2. 抽象类实现接口,可以保留抽象方法。

  3. 接口可以被接口或实现类或抽象类多实现。

接口多态

  1. 可以和对象多态一样使用在多态数组,和多态参数上。

  2. 多态传递,方法需要被重写,传递到实现类去重写。

JDK7:可以有静态方法和默认方法

JDK8:可以有私有方法

内部类

解决类的单继承问题。

  1. 局部内部类

    1. 地位是局部变量

    2. 修饰该类的修饰符和修饰局部变量一样

    3. 局部内部类直接访问外部类成员

    4. 作用域下外部类创建对象之后再访问内部类

    5. 作用域是所在方法

    6. 内部类调用外部类重名成员(调用外部类:外部类名+this+成员)

  2. 匿名内部类

    1. 同局部内部类的区别

    2. 是一个没有名称的类【名称:外部类名$数字】

    3. 还是一个构造器创建的对象

  3. 成员内部类

    1. 地位是普通属性

    2. 修饰该类的修饰符和修饰普通属性一样

    3. 成员内部类直接访问外部类成员

    4. 作用域下外部内创建对象再访问内部类

    5. 作用域是所在对象

    6. 内部类调用外部类重名成员(调用外部类:外部类名+this+成员)

  4. 静态成员内部类

    1. 地位是静态属性

    2. 修饰该类的修饰符和修饰普通属性一样

    3. 静态内部类直接访问外部类静态成员

    4. 作用域下外部内创建对象再访问内部类

    5. 作用域是所在类对象

枚举和注解

枚举

解决存放有限特定的对象问题

普通类实现枚举

  1. 构造器私有化

  2. 去掉set方法

  3. 创建实例给静态常量

枚举类

  1. 默认继承Enum类

  2. 枚举类型默认是静态常量,创建的对象

  3. 【枚举类有枚举对象,隐式继承Enum以外就是一个普通类】

注解

解决给代码提供解释信息,配置书写的一种形式。

  1. 继承Annotation接口。

  2. 定义时就是定义一个抽象方法,可以给默认值。

  3. 使用直接给方法名赋值。

元注解

  1. @Target使用目标位置【类,属性,方法,参数,构造函数,局部变量,注解,包,类型参数,类型使用】

  2. @Retention:注解声明周期【源码,字节码,运行时】

  3. @Documented:可以作为文档

  4. @Inherited:可以被继承

异常处理

解决出现异常的时候程序任然能继续运行。

抛出的异常信息系统会封装成对应的异常

  1. 具体异常类

  2. 异常相关信息

  3. 异常追踪

处理

  1. catch捕获异常

  2. throws或throw抛出异常【默认throws】抛给方法调用处

catch

  1. 没有出现异常不会进入catch

  2. 出现异常try后面代码不运行直接进入catch

  3. catch可以有多个从上往下一一匹配【父类在下面】

finally

  1. 无论出不出现异常都会执行

return

  1. return最后出现在哪里就会返回哪里的值

自定义异常

  1. 继承异常类

  2. 将异常信息向父类调用

常用类

Wrapper类

包装类类型

解决基本类型没有对应的处理方法

八种基本数据类型对应的引用类型

  1. int基本数据类型对应Integer引用类型

  2. char基本数据类型对应Character引用类型

拆箱装箱

解决包装类型的使用。

JDK1.5自动拆箱装箱:直接将相关类型进行赋值。【底层是valueOf和intValue】

拆箱:intValue

装箱:Integer.valueOf【在构造函数上加了一个字节的数字缓存】

String类型转换

解决基本类型或包装类型和字符串的关联。

转成包装类

  1. Integer的构造方法【底层调用对应的parse类型方法,character类型直接使用String的charAt方法】

转成字符串

  1. String类的valueOf【数值类型调用的是对应的toString方法,boolean是判断true或false,字符是使用字符数组创建字符串】

  2. 数值加上双引号【底层还是toString】

Integer特点

解决缓存int类型一个字节使用最频繁的数字,来提高速度。

  1. Integer包装类的valueOf方法有一个字节的缓存。

  2. 只要有基本数据类型==判断的是值是否相等

String

解决字符序列的保存,本质是类中维护char数组常量。

创建

  1. 引号引起来【指向常量池】

  2. new一个String类【先指向堆中String对象再指向常量池】

Intern方法

  1. 池中已经存在了就【指向常量池】

  2. 池中没有就new一个String类【指向常量池新创建的字符串常量】

StringBuffer

解决用可变字char数组代替String对象数组。

  1. StringBuufer保存的是临时char数组

  2. 真正保存数组的是抽象父类AbstractStringBuilder中的value

  3. 默认初始化StringBuffer的容量是16

  4. 添加一个空字符串会往里面加上null

  5. 容量不够扩容2被+2个容量,最大容量是Integer最大值

StringBuilder

解决StringBuilder所有方法都没有StringBuffer上的锁。

Math

解决数学运算的API。

  1. 正数类型的int和long

  2. 浮点类型的float和double

Arrays

解决数组的操作工具类。

排序

  1. 自然排序

  2. 定制排序:传入Comparator接口实现类

System

解决系统相关信息的获取。

大数据处理

解决比较大的数计算。

  1. 范围更大的整数:BigInterger

  2. 高精度浮点数:BigDecimal

除法需要注意到除不尽的情况。

日期

解决日期的使用。

  1. Date和SimpleDateFormat

  2. Calender

  3. LocalDate

Date和SimpleDateFormat

解决简单的日期获取设置,基于时区的毫秒数。

  1. Date:获取当前时间毫秒数

  2. SimpleDateFormat:格式化Date时间

    1. 构造参数是格式化的格式

    2. format方法是将Date转成String

    3. parse方法是将String类型解析成Date

Calendar

解决日期的拆分,并且增删改问题,还可以修改时区

  1. getInstance方法获取Calendar对象

  2. 使用get方法传入对应的参数【比如Calendar.YEAR】

LocalDate

解决日期的计算问题,丰富的API

优点

  1. 可变性:增删改

  2. 偏移量:Date从1900年开始

  3. 格式化:Calendar不能格式化

  4. LocalDate:可以处理润秒【每隔两天多一秒】

时间API

  1. LocalDate:日期【API】

  2. LocalTime:时间【API】

  3. LocalDateTime:日期时间【API】

  4. now方法获取对象

  5. get类型获取对应时间数据

格式化API

  1. DateTimeFormatter类【API】

  2. ofPattern方法定义格式

  3. format(时间API)进行格式化

时间戳API

  1. Instant类【API】

  2. now方法获取时间戳

  3. Date的from静态方法能将Instant转成Date

  4. Date的toInstant方法能将Date转成Instant

集合

解决存放Object类型。

Collection

解决单个值的集合。

遍历
  1. 迭代器:Collection集合实现了Iterable接口的都可以使用迭代器

  2. 增强for:集合和数组都可以使用增强for遍历

  3. fori循环:list集合和数组都可以使用fori遍历

List

解决有序的单列集合。

  1. 存取有序

  2. 有索引

  3. 可重复

在Collection的基础上增加了有关下标的方法。

ArrayList

解决以数组为数据结构的集合。

  1. 默认构造函数创建一个空对象数组

  2. 第一次添加最低开辟空间为10个容量

  3. 超过容量了才会扩容,增加容量是(原来容量+原来容量除2)

  4. 扩容过后还不够,直接扩容到所需容量

  5. 数组的最大长度是int的最大值

  6. 可以添加任意个null

Vector

解决以数组为数据结构并且是线程安全的集合。

  1. 默认构造函数创建10个容量

  2. 超过了容量才会扩容,增加容量是(原来的两倍)

  3. 【要是设置了容量增长个数,就是(原来容量+增长个数)】

  4. 扩容过后还不够,直接扩容到所需容量

  5. 数组的最大长度是int的最大值

  6. 可以添加任意个null

LinkedList

解决以双向列表和双端队列数据结构的集合

  1. 集合属性维护前后两个节点

  2. Node内部类维护前后两个Node节点和本类数据

  3. 每一次操作都是两端开始【双端队列】

  4. 可以添加任意个null

Set

解决不重复元素的单列集合。

  1. 不重复

  2. 无索引

  3. 存取无序

在Collection的基础上没有方法增加。

HashSet

解决以hash表为数据结构的集合

  1. HashSet里面维护了一个HashMap集合

  2. 存放数据是将HashSet的数据存放到HashMap的key中,HashMap的value使用空值常量

  3. 可以为null

LinkedHashSet

解决以hash表为数据结构还维护了一个双向链表。

  1. LinkedHashSet全是调用HashSet的方法,维护了一个LinkedHashMap

  2. 可以为null

TreeSet

解决以红黑树为数据结构的集合

  1. 底层维护了一个TreeMap

Map

解决双列数据的集合

  1. 所有的Key都和Set的值一样

  2. 唯一不同的是,Set使用的value是常量

遍历

Map中的Node元素遍历方法。

  1. entrySet方法获取所有的k-v

  2. keySet方法获取所有的k

  3. values方法获取所有的v

HashMap

解决以Hash表为数据结构的集合

扩容机制

  1. 默认构造不给数组赋值

  2. 第一次添加会扩容到16个容量

  3. 根据key计算数组的索引【计算下标】

  4. 情况一:hash处理之所在数组下标为空,直接存放到table数组

  5. 情况二:hash处理之所在数组下标不为空

    1. 情况一:找到根节点【重复不添加】

    2. 情况二:找到根节点,为树结构【树结构添加】

    3. 最后:先遍历链表

      1. 如果结尾为空直接存放,如果链表长度等于8【树化】

      2. 如果链表中数据【重复不添加】

    4. 最后:添加成功

      1. 【节点介入后】【LinkedHashMap扩展方法】

  6. 判断达到0.75的阈值进行扩容【扩容】

  7. 【插入节点后】【LinkedHashMap扩展方法】

中括号解析

  1. 【计算下标】(key的hash值异或key的hash无符号右移16位)再与计算数组最大下标

  2. 【重复不添加】(key的值相等或者key的equals相等)

  3. 【树化】

    1. 情况一:数组容量小于64先扩容

    2. 情况二:红黑树化

  4. 【树结构添加】

  5. 【扩容】

    1. 情况一:原来表的容量大于0

      1. 情况一:原来容量达到2的30次方(Integer最大值)

      2. 情况二:没达到2的30次方且容量达到16【两倍扩容】

    2. 情况二:阈值大于0(将阈值赋值给新的容量)

    3. 情况三:新的容量为16,新的阈值为0.75*16

    4. 如果阈值等于0

      1. 新容量和阈值都小于2的30次方,返回0.75阈值

      2. 否则返回Integer的最大值阈值。

    5. 遍历复制数据【第一个不为空才复制】

      1. 情况一:下一个为空,直接找到对应下标存放

      2. 情况二:红黑树遍历

      3. 情况三:链表遍历

数据结构

  1. 链表:Node元素是维护了(key的hash处理值,key,value,下一个Node节点)

  2. 红黑树:TreeNode元素维护了(父节点,左子节点,右子节点,上一页节点,红黑判断)间接继承了Node元素

LinkedHahsMap

解决以hash表为数据结构还维护了一个双向链表。

  1. 默认初始化是16个容量,最大初始化是2的30个容量

  2. 扩容机制和HashMap一样

TreeMap

解决以红黑树为数据结构的集合。

  1. 以key值作为比较

  2. 没给Comparator比较器,使用Comparable比较【类实现】

  3. 给了Comparator比较器,就不使用默认比较器【构造传入】

HashTable

解决线程安全的hash表。

  1. K和V都不能为空

  2. value可以覆盖

  3. 默认构造函数初始容量是11

  4. 下标计算【hashcode与上一个Integer最大值,再对容量取模】.

  5. 【扩容】两倍+1的扩容机制。

Properties

解决加载properties文件的集合。

  1. 本身继承自HashTable,集合和HashTable如出一辙

  2. 可以使用该集合读取Properties配置文件

Collections

解决集合的通用处理方法。

泛型

解决数据类型的类型定义。【默认Object】

声明泛型

  1. 类:普通属性,普通方法

  2. 接口:普通方法,抽象方法

  3. 泛型方法:可以声明

  4. 静态方法:必须在方法中定义

定义泛型

  1. 确定属性:只有类上定义可以使用

  2. 确定返回值

  3. 确定参数

使用

  1. 类:类上的泛型创建对象时候确定

  2. 接口:继承接口或者实现接口时候确定

  3. 泛型方法:调用的时候确定

继承和通配符

解决数据类型的类型定义的范围。

  1. ?:是通配符,表示数据类型可用范围

  2. extends A:A类及其子类

  3. super A:A类及其父类

多线程

解决多个任务同时进行。

并发并行

  1. 并发:一个处理器交替处理多个线程

  2. 并行:同一时刻多个处理器处理各自线程

Thread和Runnable

  1. Thread启动线程是start0的本地方法

  2. 调用本地方法之后,将该方法放入可运行线程

  3. 实际线程的调用由底层JVM虚拟机调用

Thread方法

【Boolean终止线程】

  1. setName:设置线程名

  2. getName:返回线程名

  3. setPriority:设置线程优先级

  4. getPriority:获取线程优先级

  5. sleep:休眠

  6. interrupt:中断线程【中断休眠】

  7. yield:让行

  8. join:插入其他线程

  9. setDaemon(true):设置为守护线程

线程状态

  1. NEW:刚创建

  2. RUNNABLE:可运行【Ready就绪和Running运行】

  3. BLOCKE:阻塞

  4. WAITING:等待

  5. TIMED_WAITING:超时等待

  6. TERMINATED:已退出

同步机制

解决多线程中数据只允许一个线程访问。

同步代码块

解决可运行的代码使用对象锁,保证同步。

  1. 格式:synchronized(对象){}

  2. 对象:互斥锁标记

同步方法

解决方法使用锁,保证方法同步。

  1. 格式:方法修饰符位置使用synchronized

  2. 静态方法:对象锁为类对象

  3. 普通方法:对象锁为当前对象

对象互斥锁

解决同步机制的问题。

  1. 在多线程中线程获取对象来执行同步代码

  2. 对象加锁,一次只能有一个线程获取该对象

释放锁

解决同步锁配合使用问题。

释放锁

  1. 当前同步代码块,同步方法执行完毕。

  2. 方法中break或return。

  3. 出现异常。

  4. wait方法。

不释放锁

  1. sleep:进入超时等待状态,不会释放锁

  2. yield:让行,还是在运行状态

IO流

解决信息传输,网络上内存对内存传输,本机上内存对硬盘传输。【必须关闭流】

文件

解决磁盘存放资源问题。

资源路径

  1. 构造方法找到资源路径

  2. getParent:获取父路径

  3. getName:获取当前名称

  4. getAbsoluteFile:获取绝对路径

文件文件夹判断

  1. exitsts:是否存在

  2. isFile:是文件

  3. isDirectory:是文件夹

  4. listFile:获取列表

文件

  1. createNewFile:创建文件【单级创建】

  2. length:文件大小

  3. delete:删除文件

文件夹

  1. mkdir:创建一级目录

  2. mkdirs:创建多级目录

  3. delete:删除空目录

File输入流

解决资源输入。

分类

  1. 字节输入流

  2. 字符输入流:本质是输入转换流的子类

使用

  1. 读取一个字节/字符

  2. 读取一个字节/字符数组【可截取】

  3. 估计文件字节/字符数量【可一次全部读取】

  4. 跳过字节/字符读取个数

返回读取有效长度,读完返回-1。

File输出流

解决资源输出。【必须刷新】【追加和覆盖】

分类

  1. 字节输出流

  2. 字符输出流:本质是输出转换流的子类

使用

  1. 写一个字节

  2. 写一个字节数组【可截取】

Buffer缓冲流

解决批量处理数据提供方法。

  1. 字符输入缓冲流:readLine读取一行

  2. 字符输出缓冲流:newLine换行【和系统相关】

  3. 字节输入缓冲流:内置数组

  4. 字节输出缓冲流:内置数组

Object处理流

解决存放数据的同时将数据类型也一并保存。

序列化:ObjectOutputStream

  1. 输出的时候write类型

  2. 默认所有的属性都参与序列化,除了static和transient成员

  3. 要求类中的属性都要实现Serializable接口

反序列化:ObjectInputStream

  1. 读取顺序和写出一致

  2. 有对应的类引用,向下转型

  3. 输入的时候read类型

Serializable

  1. 参与序列化的类都要实现Serializable接口

  2. 该接口有传递性,父类有子类就有了

  3. SerialVersionUID序列号,当类修改了可以根据序列号找到反序列化的类

标准输入输出流

解决最基础的输入输出。

标准输入流:System.in

  1. 键盘输入:Scanner

  2. 编译类型:InputStream

  3. 运行类型:BufferInputStream

标准输出流:System.out

  1. 显示器输出:

  2. 编译类型:PrintStream

  3. 运行类型:PrintStream

转换流

解决将字节流转成字符流,根据编解码方式转换。

输入转换流:InputStreamReader。解码字符集

输出转换流:OutputStreamWriter。编码字符集

打印流

解决输出时候自动刷新。

打印字节流:PrintStream

打印字符流:PrintWriter

Properties配置

解决properties配置文件的读取和操作,本身就是一个集合。

格式:键=值

方法

  1. load:加载文件到properties集合

  2. list:输出到指定设备

  3. getProperties:获取值

  4. setProperties:设置键值对

  5. store:将键值对保存到配置文件【Unicode编码】

网络

解决计算机和计算机之间的通信问题。

网络信息

解决网络标识问题。

网络范围

  1. 局域网:计算机连接网络的同一个设备

  2. 城域网:以城市为范围

  3. 广域网:比城市范围更大【互联网】

IP

解决计算机在网络中的标识。【ipconfig查看IP】

  1. IPv4

    1. 格式:xx.xx.xx.xx

    2. 范围:xx取值0-255

    3. 意义:以网络号+主机号组成

    4. 分类【一半的一半】

      1. A类:0+7+24

      2. B类:10+14+16

      3. C类:110+21+8

      4. D类:1110+28【广播】

      5. E类:11110+27【待用】

      6. 【127.0.0.1】

    5. 购买的服务器IP才是固定的

域名

解决IP记忆问题。【根据域名映射成指定的IP】

端口号

解决计算机上的程序标识问题。【netstat -an|more】

  1. 取值范围:0-65535

  2. 已经占用:0-1024

  3. 常见端口:tomcat8080,mysql3306等

网络通信协议TCP/IP

解决数据传输中的编解码问题。

  1. 用户数据

  2. 应用HTTP:加上APP首部

  3. 传输TCP/UDP:加上TCP首部

  4. 网络IP:加上IP首部

  5. 以太网驱动:加上首位帧

TCP协议

解决数据传输时建立传输通道。

  1. 需要连接和释放连接【三次握手,四次挥手】

  2. 可进行大量数据传输

UDP协议

解决无连接数据传输。

  1. 将数据,源,目的封装包传输

  2. 数据报大小限制64K

InetAddress

解决Ip地址相关问题。

  1. getLocalHost:获取本机InetAddress对象

  2. getByName:获取指定主机名/域名InetAddress对象

  3. getHostName:获取对象的主机名

  4. getHostAddress:获取对象的地址

Socket

解决TCP通信问题

  1. 需要两个Socket进行IO传输

  2. 主动发起通信的是客户端,服务端阻塞等待客户端发送请求

使用

  1. 客户端:Socket(IP地址,端口),发送请求

  2. 服务端:ServiceSocket(端口),监听端口等待连接【阻塞】

    1. ServiceSocket.accept:获取Socket对象

  3. 输入流读取【阻塞】

  4. 输出流写出:socket.shutdownOutput();【结束标记】【flush】

UDP

解决数据报无连接数据传输。

接收端

  1. DatagramSocket:接收数据报【监听端口】receive

  2. DatagramPacket:参数字符数组

发送端

  1. DatagramSocket:接收数据报【发送端口】send

  2. DatagramPacket:UDP数据报,接收端IP和端口

反射

解决根据路径的字符串创建对象的方法。

创建实例

  1. Class.newInstance:创建实例

类对象

获取类对象

  1. Class.forName:编译阶段

  2. Class.class:加载阶段

  3. class.getClass:运行阶段

  4. ClassLoader.loadClass:类加载器加载全类名

  5. 基本类型.class

  6. 包装类型.TYPE

使用类对象方法

  1. getClassLoader:获取类加载器

反射方法

获取方法对象

  1. Class.getMethod(名称,参数列表)【仅公共】

  2. Class.getDeclaredMethod(名称,参数列表)【仅类中声明】

使用方法对象

  1. setAccessible:暴力调用

  2. Method.invoke(对象)调用方法

反射属性

获取属性对象

  1. Class.getField(名称)【仅公共】

  2. Class.getDeclaredField(名称)【仅类中声明】

使用属性对象

  1. get(对象)

  2. set(对象,值)

反射构造

获取构造对象

  1. getConstructor(参数)【仅公共】

  2. getDeclaredConstructor(参数)【仅类中声明】

使用构造对象

  1. newInstance

有Class对象的类型

  1. 类,成员内部类,静态内部类,局部内部类,匿名内部类

  2. 枚举

  3. 接口

  4. 注解

  5. 数组

  6. 基本类型

  7. void

动态加载,静态加载

静态:加载的类信息中只要有new就会被加载。

动态:不执行的时候不会创建对象,也不会报错

JDBC

只需要一个MySQL驱动包。

解决关系型数据库的统一规范。【本质是数据交互关闭流】

DriverManager

解决数据库驱动的管理

  1. Driver驱动类固定:com.mysql.cj.jdbc.Driver

  2. 原始管理驱动:DriverManager.registerDriver(new Driver());

  3. JDK5之后的jdbc4会自动找到jar包下META-INF\services\java.sql.Driver去注册

Connection

解决客户端和数据的连接问题

  1. 获取连接:DriverManager.getConnection(url,username,password);

  2. url:jdbc:mysql://IP:port/库名?【serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true&rewriteBatchedStatements=true】

  3. user:账号

  4. password:密码

Statement

解决向数据库发送静态SQL。

  1. Connection.createStatement:获取声明对象

  2. execute:执行CRUD返回boolean

  3. executeQuery:执行查询返回resultSet

  4. executeUpdate:执行增删改返回int

Result

解决数据库获取结果集【List<Map>结构】

  1. next:光标从第一行前面开始向下走,有数据返回true,没有数据返回false

  2. get类型(int):根据列的第几列去取值

  3. get类型(String):根据列的标签去取值

PreparedStatement

解决向数据库发送动态SQL。

  1. SQL语句以?来占位

  2. Connection.prepareStatement(SQL语句):获取预编译声明对象

  3. set(index):给?设置

  4. executeQuery:执行查询返回resultSet

  5. executeUpdate:执行增删改返回int

主键回显

解决主键自增长回显功能

  1. Connection.prepareStatement(SQL语句,Statement.RETURN_GENERATED_KEYS):

  2. PrepareStatement.getGeneratedKeys():将主键结果封装到resultSet中

批量插入

解决插入的数据过多。

  1. addBatch:不执行,追加values后面

  2. executeBatch:批量执行

  3. url上设置rewriteBatchedStatements=true

  4. SQL语句不能使用;号

JDBC事务

解决JDBC中的事务问题。

  1. JDBC的事务是自动提交。

  2. JDBC事务使用Try,Catch

  3. JDBC以连接为单位

连接池

只需要Mysql驱动包和Druid的依赖。

解决创建连接关闭连接浪费时间的问题。

DataSuorce

连接池统一规范。【Druid】

Druid

解决数据库连接的最优秀连接池。

  1. DruidDataSourceFactory.createDataSource(prop配置文件):工厂创建连接池

  2. DruidDataSource:连接池接口实现

  3. 设置连接

    1. setDriverClassName:设置driver

    2. setUrl:设置url

    3. setUsername:设置user

    4. setPassword:设置password

  4. getConnection:获取连接

  5. Connection.close:回收连接

【为同一个线程任何位置都是取到同一个连接,线程绑定数据源】

DBUtils

解决JDBC的封装工具

  1. QuertRunner(DataSource):核心API可以绑定数据源

  2. ResultSetHandler:结果集处理器【handle方法处理结果集】

  3. SQL:书写用?代表占位符

正则表达式RegExp

解决提取文章中的复合表达式规则的数据。

步骤

  1. 模式编译:Pattern.compile("\d\d");

    1. 完整匹配:Pattern.matches(regex, CharSequence)

  2. 获取匹配器:compile.matcher(s);

  3. 开始匹配:matcher.find()【返回是否匹配到】

    1. 找到结果,将结果记录在matcher属性中

    2. oldLast:记录下一个开始匹配的下标。

    3. groups数组:记录【每一组】的下标

  4. 获取匹配结果:matcher.group(0)

    1. group(int):从【第几组】下标截取字符串

元字符

转义字符:\

匹配符

  1. []:可以接收的单个字符。

  2. [^]:排除接收的单个字符。

  3. -:连字符一定的范围。

  4. .:可以接收任意一个非空格符号

  5. \\d:可以接收单个数字【大写取反】

  6. \\w:可以接收单个数字和字母【大写取反】

  7. \\s:可以接收任何空白【大写取反】

  8. 【(?!):后面的字母不区分大小写】

选择符

  1. |:选择前面一种或者后面一种,最大范围选择

限定符

  1. *:任意次数

  2. +:最少一次

  3. ?:最多一次

  4. {n}:n次

  5. {n,}:最少nci

  6. {n,m}:n次到m次

  7. 【后面加?:非贪心捕获,最小数量匹配。】

定位符

  1. ^:定位开始字符

  2. $:定位结束字符

  3. \\b:匹配字符结尾有空格【大写取反】

分组

捕获分组

  1. (pattern):非命名捕获。从左往右1开始排号

  2. (?<name> pattern):命名捕获。还可以使用组名获取分组

非捕获分组

  1. (?: pattern):局部选择。

  2. (?= pattern):处于结尾,前面的字符匹配就选择。

  3. (?!pattern):处于结尾,前面的字符匹配不选择。

反向引用

解决已经分组捕获的内容【后】进行引用。

  1. \\分组号:内部反向引用,表达式内部使用

  2. $分组号:外部反向引用。

  3. $使用:matcher.replaceAll("$1"):使用反向引用代替匹配的字符。

多线程超卖

JAVAWeb

HTML

解决页面内容书写。

格式

解决HTML文件书写格式。

  1. 声明

  2. html根标签

    1. 首部

      1. meta

      2. title

    2. 尾部

内容

解决HTML文件最基本的组成

  1. 单标签

  2. 双标签【内容】

  3. 属性

    1. 基本属性

    2. 事件属性

语法

解决使用HTML的最基本规则。

  1. 【注释】<!-- -->

  2. 大小写不敏感

  3. 标签不能交叉嵌套

  4. 标签必须闭合

  5. 属性必须有值且值要加引号

标签

解决HTML编写问题【使用W3cSchool】

base参照地址:href当前标签地址。其他标签的href相对地址会根据该标签去访问。

html字符实体:&打头;结尾

font:字体标签

br:换行标签

h1-h6:标题标签

a:超链接。href写url连接,target响应目标页面显示。

ol或ul:ol是有序列表,ul是无序列表。li是列表项。

img:显示图片。src路径。

table:表格。tr行,td格,th标题格。colspan跨列,rowspan跨行。

ifarme:内嵌窗口。

div:独占一行。

span:片段。

p:段落。

表单

解决表单提交数据。

form

  1. action:服务器地址

  2. method:提交方式

input

  1. text:文本框

  2. password:加密文本框

  3. select:下拉框。option选项标签【selected="selected"代表选中】

  4. redio:单选框【checked="checked"代表选中】

  5. checkbox:多选框【checked="checked"代表选中】

  6. textarea:多行文本框

  7. reset:重新到默认选择

  8. submit:提交按钮

  9. button:按钮

  10. file:文件上传

  11. hidden:隐藏域

GET请求

  1. 地址栏:action+?+请求参数

  2. 长度有限制

POST请求

  1. 地址栏:只有action

  2. 没有长度限制

路径

java路径

  1. 绝对路径:从盘符开始

  2. 相对路径:/服务器解析http:/ip:port/工程路径

web路径

  1. 绝对路径:从HTTP开始

  2. 相对路径:从当前所在目录开始

    1. .标识当前目录

    2. ..上一级目录

    3. 文件名相当于./文件名

    4. /浏览器解析:http:/ip:port/

特殊:sendRediect("/")会交给浏览器解析

CSS

解决网页页面美化问题。

语法

  1. 注释/* */

  2. 选择器{属性:值;}

使用方式

方式一:属性直接使用

  1. html的style属性:style="key: value;"

方式二:头标中

  1. <style type="text/css">中使用下面的代码

  2. 选择器{属性:值;}

方式三:头标中引入外部文件

  1. <link rel="stylesheet" type="text/css" href="web路径"/>

  2. 外部文件书写:选择器{属性:值;}

选择器

  1. 标签名选择器:标签名{}

  2. id选择器:#id值{}

  3. class选择器:.class值{}

  4. 【多个选择器使用逗号隔开】

JS

解决网页动态显示问题。

使用方式

方式一:头或尾标签种使用script标签

  1. <script type="text/javascripe">标签下写代码

方式二:头文件种进行外部引入

  1. <script type="text/javascripe" src="web路径">

语法

变量

类型

  1. number:数值

  2. string:字符串

  3. object:对象

  4. boolean:布尔

  5. function:函数

特殊值

  1. undefind:未初始化

  2. null:空值

  3. NAN:不是数字

运算

关系运算

  1. ==:比较内容

  2. ===:比较内容和类型

逻辑运算

  1. &&:返回第一个错误的值或者返回最后一个正确的值

  2. ||:返回第一个正确的值或者返回最后一个错误的值

  3. !:取反

  4. 【0,null,undefined,空串。都是false】

函数

函数名称相同会被覆盖掉。

隐形参数arguments

定义

方式一:function定义

  1. function 函数名(形参列表){}

方式二:函数赋值给变量

  1. var 函数名 = funcation(形参列表){}

函数例子

  1. alert:提示框

  2. typeof:返回数据类型

对象

定义

方式一:花括号定义

  1. var 对象名 = {};

方式二:对象赋值给变量

  1. var 对象名 = new Object{};

数组
  1. []:空数组

  2. [1,53,'asd']:定义数组同时初始化

事件

事件注册

静态注册

  1. 使用事件种类的属性名

  2. 事件属性名="事件没有;结束"

  3. 事件属性名="函数调用"

动态注册

  1. 获取标签的dom对象

  2. dom对象.事件名=function(){}

页面加载事件

  1. 固定:window.οnlοad=函数

事件种类
  1. onload:页面加载完成

  2. onclick:单机

  3. oblur:失去焦点

  4. onchange:内容发送变化

  5. obsubmit:表单提交

DOM对象

获取对象

  1. 根据id获取:document.getElementById(id)

  2. 根据name获取:document.getElementByName(Name)

  3. 根据标签类型获取:document.getElementByTagName(TagName)

RegExp正则表达式

标准使用

  1. new RegExp(pattern):获取模板对象

  2. regExp.test:判断是否包含

简单使用

  1. var regExp= /pattern/:获取模板对象

  2. regExp.test:判断是否包含

JQuery

只需要一个JQuery的文件。

核心对象

解决$代表JQuery对象

  1. 传入函数:页面加载之后执行。

  2. HTML字符串:创建元素节点对象。

  3. 选择器字符串:查找相关节点对象。

  4. DOM对象:将DOM对象包装成JQuery对象。

DOM和JQuey对象

DOM对象

  1. 表现形式:alert出来是[object HTMLButtonElement]

  2. document获取的对象都是DOM对象

JQuey对象

  1. 表现形式:alert出来是[object object]

  2. JQuery函数返回的对象都是JQuery对象

  3. 本质上是一个对DOM对象数组

XML

格式
  1. 文档声明

  2. 元素

语法

  1. 注释:<!-- -->

  2. CDATA:<![CDATA[不解析内容]]>

dom4j解析

只需要一个依赖包

  1. SAXReader对象

  2. read方法读取xml文件:获取document对象

Tomcat

目录

  1. bin:可执行命令

  2. conf:配置文件

  3. lib:依赖包

  4. logs:日志存放

  5. temp:临时数据

  6. webapps:部署工程

  7. work:存放运行时jsp翻译的servlet源码,session钝化(序列化)

启动关闭服务器

启动

  1. 方式一:startup.bat点击

  2. 方式二:DOS窗口运行startup.bat

关闭

  1. 方式一:shutdown.bat点击

  2. 方式二:关闭黑窗口

【使用了JAVA_HOME的环境变量】

配置

端口号:conf/server.xml下边

部署工程

方式一

  1. 把web工程放在webapps目录下即可

方式二

  1. conf/Catalina/loadhost下放一个xml文件

  2. xml文件书写:<Context path="/工程路径" docBase="工程绝对路径"/>

Servlet

只要servlet-api依赖。

使用
  1. 实现servlet接口

  2. web.xml配置映射信息

Servlet生命周期

  1. 构造方法:第一次访问时候创建对象

  2. init方法:对象创建完成之后初始化

  3. service方法:每一次访问都会调用

  4. destroy方法:容器关闭的时候调用

ServletConfig

  1. 获取初始化参数<init-param>

  2. 获取ServletContext对象

  3. 获取程序别名<servlet-name>

  4. 维护父类变量:重写了初始化方法,其他方法getServletConfig是从父类获取】

ServletContext

  1. 获取工程信息

  2. 获取工程<context-param>

  3. 域对象保存数据

HTTP请求

  1. 请求行

    1. 请求方式

    2. 请求路径

    3. 协议版本号

  2. 请求头:K-V

  3. 请求空行【get请求没有】

  4. 请求体【get请求没有】

POST请求目前只有form表单能发送

HTTP响应

  1. 响应行

    1. 协议版本号

    2. 状态码

    3. 状态码描述

  2. 响应头:K-V

  3. 响应空行

  4. 响应体

响应码

  1. 200:成功

  2. 302:重定向

  3. 404:请求地址错误

  4. 500:服务器内部错误

MIME

HTTP协议中数据类型。

HttpServletRequest

解决请求到服务器之后,自动将请求数据封装到HttpServletRequest,传递给service方法使用

  1. getRequestURL:获取请求路径

  2. getMethod:获取请求方式

  3. getRequestHeader:获取请求头

  4. getParameter:获取value为单值的参数

  5. getParameterValues:获取value为多值的参数

  6. setAttribute:向request域中存放数据

  7. getAttribute:从request域中获取数据

请求POST中文乱码

  1. setCharacterEncoding("UTF-8"):设置请求体的字符集

  2. 在获取请求参数之前调用

请求转发

  1. getRequestDispatcher("/转发路径").forward(req,resp);

HttpServletResponse

解决请求到服务器之后,自动创建一个新的HttpServletResponse,传递给service方法使用

  1. getOutputStream:获取响应字节流

  2. getWriter:获取相应字符流

响应中文乱码

  1. getCharacterEncoding:默认是ISO-8859-1,欧洲编码

  2. setCharacterEncoding("UTF-8"):设置服务器字符集UTF-8

  3. 浏览器默认是GBK

  4. setHeader("Content-type","text/html;charset=UTF-8"):设置相应解析编码

  5. 【综合上面:setContentType("text/html;charset=UTF-8")】

  6. 获取相应流之前设置才有效

请求重定向

  1. setStatus(302):设置相应编码

  2. setHeader("Location","请求路径"):设置重定向地址

  3. 【综合上面:setRedirect("请求路径")】

JSP

只需要一个jsp-api依赖。

JSP本质是servlet的另一种书写形式。

格式
  1. <%@ page contentType="text/html;charset=utf-8" languge="java" %>

  2. HTML标签

一共有三种指令

  1. page指令。jsp配置信息。

  2. include指令。动态包含。也可以写成<jsp:include>。

  3. taglib指令。引入JSTL标签库。

脚本

  1. 声明脚本:<%! 定义类的代码 %>【serlvet类中】

  2. 表达式脚本:<%= jsp页面输出数据 %>【_jspService方法的out.print代码】所以不能以分号结尾

  3. 代码脚本:<% java语句 %>【_jspService方法中】

三种注释

  1. html注释:<!-- 表达式脚本中 -->

  2. java注释:<% 传递到servlet源码中 %>

  3. jsp注释:<%-- 注释掉所有的内容 --%>

内置对象九

  1. request

  2. response

  3. pageContext

  4. session

  5. application

  6. config

  7. out

  8. page

  9. exception【需要开启】

四大域对象

  1. pageContext

  2. request

  3. session

  4. application

out和response

  1. 他们各自输出到自己的缓冲区

  2. 然后out将自己缓冲区的内容追加到response缓冲区

  3. 最后由response缓冲区将数据相应给浏览器

out对象

  1. write:直接将数据返回给浏览器

  2. print:在write的基础上对各种数据都进行了String类型处理

静态包含

  1. 格式:<%@ include file="/"%>

  2. 静态包含是将另外一个jsp的页面内容放在引入标签位置,生成一个servlet。

动态包含

  1. 格式:<jsp:include page=""/>

  2. 动态包含是将另外一个jsp对应的servlet的方法调用。

转发

  1. 格式:<jsp:forward page="路径"/>

  2. 【JSP不能直接相应客户端】

JSP的6个动作

  1. <jsp:include > 动态包含

  2. <jsp:forward > 请求转发

  3. <jsp:param > 设置请求参数

  4. <jsp:useBean > 创建一个对象

  5. <jsp:setProperty > 给指定的对象属性赋值

  6. <jsp:getProperty > 取出指定对象的属性值

Listener

三大对象创建销毁监听

  1. ServletContextListener

  2. HttpSessionListener

  3. ServletRequestListener

三大对象域内容增删改

  1. ServletContextAttributeListener

  2. HttpSessionAttributeListener

  3. ServletRequestAttributeListener

对象绑定

  1. HttpSessionBindingListener:实现该接口的类,存到session或者取出都会触发绑定和解绑方法。

  2. HttpSessionActivationListener:实现该接口,钝化(序列化),活化(反序列化)都是由容器执行,会调用该接口的方法。

EL

解决JSP从四大域中获取数据。Expression Language空值会输出空白而不是null。

  1. 格式:${key}

  2. 输出格式

    1. 对象和map:{}

    2. 数组:[]

    3. 其他属性:键值对

  3. 域对象中获取数据setAttribute("p",person)

    1. 输出基本属性:p.name

    2. 输出数组属性:p.arr

    3. 输出数组元素:p.arr[下标]

    4. 输出map集合属性:p.map

    5. 输出map集合元素中的值:p.map.key【key值比较特殊可以[]括起来】

运算符

  1. 关系运算

  2. 逻辑运算

  3. 算术运算

  4. 三元运算符

  5. empty判断是否为空

    1. null值

    2. 空串

    3. 集合长度为0

    4. 对象数组长度为0

EL表达式11个隐含对象

  1. pageContext:page上下文

  2. pageScope:page域

  3. requestScope:request域

  4. sessionScope:session域

  5. applicationScope:application域

  6. param:获取单值参数

  7. paramValues:获取多值参数

  8. header:获取单值请求头

  9. headerValues:获取多值请求头

  10. cookie:获取Cookie信息

  11. initParam:获取web.xml配置的context-param

JSTL

只需要导入taglib-standard-(impl和spec)两个依赖。

解决JSP文件中的代码脚本编写。

标签库分类

  1. 核心库:包名core。前缀c。

  2. 格式化:包名fmt。前缀fmt。

  3. 函数:包名functions。前缀fn。

  4. 数据库:三层架构,只需要Dao层访问数据库。

  5. xml:现在用json来和浏览器交互数据。

使用标签库

  1. 引入<%@ taglib prefix="前缀" url="Oracle Java Technologies | Oracle包名"%>

核心库标签

  1. forEach:遍历

  2. set:向域中设置变量

  3. if:选择执行

  4. choose:多选一。配合when和otherwise标签。

上传下载

只需要commons-(fileupload和io)两个依赖

上传

  1. 发送form表单,method=post请求,encType=multipart/form-data

  2. 表单项type=file,name表单项名


  3. ServletFileUpload类解析上传数据

  4. isMultipartContent:判断请求是多段格式数据

  5. parseRequest:解析请求【返回FileItem集合】

  6. isFormField:判断是普通表单项

  7. getFieldName:获取表单项name属性

  8. getString:获取表单项的值

  9. getName:获取上传的文件名

  10. write:文件输出到磁盘

下载

  1. ServletContext.getResourceAsStream:获取资源流

  2. ServletContext.getMimeType:获取下载文件的MIME类型

  3. resp.setContentType(mimeType):设置响应类型

  4. resp.setHeader("Content-Disposition","attachment;filename=文件名"):设置下载头

  5. 获取响应流

  6. IOUtils.copy(输入流,输出流):复制流数据

URL编解码

解决中文转成URL格式:%xx%xx%xx

谷歌和IE

  1. URLEncoder.encode("中文"):编码

  2. URLDecoder.decode(String):解码

火狐【BASE64编码】

  1. 文件名格式:=?charset?B?xxxxx?=【xxxxx就是BASE64编码】

  2. BASE64Encoder.encodeBuffer("中文".getBytes("UTF-8")):编码

  3. BASE64Decoder.decodeBuffer(String):解码

Cookie

解决浏览器数据保存。

特点

  1. 服务器创建的Cookie对象,发送到浏览器就转成了cookie请求头

  2. cookie大小不能超过4kb

使用
  1. new Cookie("key","value"):创建一个cookie对象【可以覆盖】

  2. resp.addCookie(cookie):响应给客户端

  3. req.getCookies:获取请求头中的cookie封装成cookie数组

  4. 【不支持中文等特殊字符,要使用BASE64编码】

生命控制

  1. setMaxAge方法

  2. 正数:存活秒数

  3. 负数:关闭浏览器就删除

  4. 0:立即删除

有效Cookie

  1. Cookie的path默认是当前工程路径

  2. 当发送的URL地址包含Cookie的path路径的时候,cookie才会有效

Session

解决解决服务器保存浏览器和服务器之间需要的数据。

特点

  1. 服务器创建Session对象

  2. 将SESSIONID存储到Cookie头中

使用
  1. req.getSession:第一次get是创建,第二次get就是根据cookie中的JSESSIONID获取对应的Session对象。

  2. isNew:判断是不是刚创建的。

  3. getId:获取SESSIONID值

  4. setAttribute:向session存值

  5. getAttribute:从session取值

生命控制

  1. setMaxInactiveInterval:设置超时时长

  2. getMaxInactiveInterval:获取超时时长

  3. 正数:超时时长【可以刷新】

  4. 负数:永不超时

  5. invalidate:设置会话无效

Filter

解决请求安全性。

使用
  1. 类实现Filter接口

  2. 在web.xml文件中配置映射路径

生命周期

  1. 构造方法:web启动的时候Filter就创建

  2. init初始化:Filter对象创建之后自动初始化

  3. doFilter过滤方法:每次拦截到请求就会执行

  4. destroy销毁方法:关闭服务器

FilterConfig

  1. 获取filter-name

  2. 获取init-param

  3. 获取ServletContext对象

FilterChain

异常统一处理

  1. 本来是用过滤器去转发的。

  2. 可以在web.xml配置中配置error-pagr设置异常统一转发页面

正常执行

  1. 第一个过滤器拦截到FilterChain.doFilter找到第二个过滤器

  2. 第二个过滤器拦截到FilterChain.doFilter请求资源

  3. 响应第二个过滤器FilterChain.doFilter之后的代码

  4. 响应第一个过滤器FilterChain.doFilter之后的代码

第二个过滤器拦截

  1. 第一个过滤器拦截到FilterChain.doFilter找到第二个过滤器

  2. 第二个过滤器拦截到FilterChain.doFilter拦截

  3. 响应第二个过滤器FilterChain.doFilter之后的代码【不执行】

  4. 响应第一个过滤器FilterChain.doFilter之后的代码

拦截器链是根据web.xml配置的顺序来执行。

拦截路径

  1. 精准匹配

  2. 目录匹配:*代表目录

  3. 后缀名匹配:*.html

ThreadLocal

解决当前线程存储数据。

  1. ThreadLocal对象存储在ThreadLocalMap中

  2. 每一个当前线程都绑定了一个ThreadLocalMap

  3. ThreadLocal对象简单理解为以当前线程为key,设置的值为value

JSON

只需要gson依赖。

解决服务器和浏览器数据交换的格式

定义

  1. JS中定义JSON对象:var json = {"key"="value","key"="value"};

  2. Java中定义JSON

JS转换

  1. stringify:json对象转成json字符串

  2. parse:json字符串转成json对象

Java转换

  1. 核心api是Gson

  2. toJson:将javaBean转成json字符串

    1. 对象

    2. List集合

    3. Map集合。

  3. fromJson(json字符串,Class):json字符串转成javaBean对象

  4. fromJson(json字符串,new TypeToken<>(具体类型).getType):json字符串转成list或map集合

AJAX

解决浏览器的js和服务器的数据异步交互。

原生JS

发送
  1. 核心api是XMLHttpRequest。

  2. var ajax = new XMLHttpRequest();:获取核心对象

  3. open(method,url,async)true表示异步:设置请求参数

  4. onreadystatechange:readyState发送改变自动调用该事件

  5. send(string):发送请求数据

回调
  1. 获取响应API:responseText和responseXML。

  2. status:200和404取值

  3. readyState

    1. 0:表示请求未初始化

    2. 1:表示请求已连接

    3. 2:请求已接收

    4. 3:请求已处理

    5. 4:请求已完成,准备相应

JQuery异步

格式
  1. 未封装:$.ajax(js对象);

  2. get请求封装:$.get(对应的js对象);

  3. post请求封装:$.post(对应的js对象);

  4. getJson请求封装:$.getJson(对应的js对象);

使用

$.ajax()

  1. url:地址

  2. type:mthod请求方式

  3. data:请求参数【js对象】

  4. success:回调函数【一定要加上一个参数】

  5. dataType:响应类型【text,xml,json】

$.get()和$.post()

  1. url:data:callback:type。

  2. 按照顺序直接书写value对应的js对象

$.getJson()

  1. url:data:callback。

  2. 按照顺序直接书写value对应的js对象

serialize方法

解决将表单数据转换成url格式的数据。

i18n

解决不同语言的显示。

java类中
  1. Locale:表示不同时区,位置,语言

  2. properties文件:baseName+_locale+.properties

  3. ResourceBundle

    1. getBundle:根据baseName和Locale读取配置文件

    2. getString:根据key获取里面的值

JSP中

格式化标签库

  1. fmt:setLocale:设置Locale

  2. fmt:setBundle:设置baseName

  3. fmt:message:从文件中获取值key=?

XML约束

DTD约束

内部书写

  1. 格式:<!DOCTYPE 根元素[约束]>根元素

  2. 元素约束

    1. <!ELEMENT 元素名称 类别>:类别【ANY,EMPTY】

    2. <!ELEMENT 元素名称 (子元素内容)>:元素内容【子元素,字符串#PCDATA】

    3. 出现次数:+,?,*,|。

  3. 属性约束

    1. <!ATTLIST 元素名称 属性名称 属性类型 默认值>

    2. 属性类型和默认值查找w3cschool文档

  4. 实体约束

    1. 内部实体定义:<!ENTITY 实体名称 "实体的值">

    2. 使用:【&实体名称;】

    3. 外部实体定义:<!ENTITY 实体名称 SYSTEM "URI/URL">

外部引入

  1. 将除了根元素的约束,保存到dtd文件中

  2. <!DOCTYPE 根元素 SYSTEM "DTD文件路径">:引入自定义DTD

  3. <!DOCTYPE 根元素 PUBLIC "PUBLIC ID" "DTD文件路径">:引入别人定义的DTD

XSD约束

更细致化的约束:值的范围,正则表达式,出现次数,顺序。

支持命名空间,在不同的命名空间下面,可以有重复元素名。

schema约束文件必须和xml文件分离。

schema文件

约束文件头
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">
  1. xmlns:xs="http://www.w3.org/2001/XMLSchema"

    1. xs:是前缀

    2. schema用到的元素和类型来自此命名空间,被约束

  2. targetNamespace="http://www.w3school.com.cn"

    1. schema定义的元素来自此命名空间,当前文件命名空间

  3. xmlns="http://www.w3school.com.cn"

    1. 默认的命名空间

  4. elementFormDefault="qualified"

    1. 任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定,被约束文件必须满足该约束。

约束文件定义
  1. 元素:<xs:element name="元素名称" type="元素类型" default="默认值">

  2. 属性:<xs:attribute name="属性名称" type="属性类型" default="默认值"/>

引用
<?xml version="1.0"?>
<note xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
  1. xmlns="http://www.w3school.com.cn"

    1. 默认命名空间声明,被约束的命名空间。

  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    1. XML实例命名空间,从网络中获取。【默认】

  3. xsi:schemaLocation="http://www.w3school.com.cn note.xsd"

    1. 第一个值是所需要使用的命名空间,被约束的名称空间

    2. 第二个值是给名称空间使用的XMLschema的位置,被约束文件的文件名。

Hamcrest-core测试断言依赖

Lombda

表达式

必须是函数式接口

函数式接口

解决只有一个抽象方法的接口

  1. Consumer消费型接口【有参数,无返回】

  2. Supplier供给型接口【无参数,有返回】

  3. Function函数型接口【有参数,有返回】

  4. Predicate断定型接口【判断true或者false】

使用
  1. 有参数

  2. 无参数

  3. 返回值用return

  4. 一个参数小括号可以省略

  5. 参数类型可以省略

  6. Lambda只有一条代码大括号可以省略

方法引用

解决引用方法和函数式接口方法参数和返回值一致。

方法直接替换

  1. 对象::实例方法名

  2. 类::静态方法名

方法第一个参数作为调用者出现

  1. 类::实例方法名

  2. 示例:(s1,s2)->s1.compareTo(s2)。等同于String::compareTo。

构造引用

  1. 类::new

数组引用

  1. String[]::new

Stream流

解决集合和数组的数据计算,不会存储元素,不会改变对象,只有在就终止时候才会执行。

获取流

  1. Collection.stream:顺序流

  2. Collection.parallelStream:并行流

  3. Arrays.stream(str);

  4. Stream.of();

  5. Stream.iterate(0,t->t + 2):无限迭代流

  6. Stream.generate(Math::random):无限生成流

操作流

筛选【传入条件】

  1. filter:过滤元素

  2. distinct:去重,通过hashCode和equals去重元素

  3. limit:截断流,截取前段数据

  4. skip:跳过元素,去除前段数据

映射【传入函数】

  1. map:内部元素处理获得新元素

  2. faltMap:内部流元素处理获得一个新的流

排序【传入比较器】

  1. sorted:自然排序

  2. sorted(比较器):比较器排序

终止流

匹配【传入Predicate函数】

  1. allMatch:是否匹配所有元素

  2. anyMatch:是否匹配到任意元素

  3. noneMatch:是否匹配不到元素

获取

  1. findFirst:返回第一个元素

  2. findAny:返回任意一个元素

  3. count:返回元素个数

  4. max:返回元素最大值

  5. min:返回元素最小值

  6. forEach:遍历内部元素

归约

  1. reduce(T,BinaryOperator):以T开始,执行三个T的function

  2. reduce(BinaryOperator):执行三个T的function

收集

  1. collect(Collector):收集到Collector接口的实现类

  2. Collector工具类Collectors

Optional类

解决空指针问题,空对象返回一个null。

创建对象

  1. of(T):T必须非空

  2. empty():空实例

  3. ofNullable(T):T可以为null

判断内部对象

  1. isPresent():判断是否包含对象

  2. ifPresent(consumer):如果有值就传参并执行consumer函数

获取对象

  1. get():有对象返回对象,没对象报错

  2. orElse(Object other):有对象返回对象,没对象返回other

  3. orElseGet(Supplier):有对象返回对象,没对象返回Supplier提供的对象

  4. orElseThrow(Supplier):有对象返回对象,没对象返回Supplier提供的异常

动态代理

不改变源码的情况下给实现方法进行增强。

静态代理

将(目标对象)和(增强代码的对象)交给(目标对象的另一个实现类),再调用代理类将两个对象传给代理类。

JDK动态代理

解决有接口的实现类的不修改源码增强。

定义

public class MyInvocationHandler implements InvocationHandler {
    Object o;

    public MyInvocationHandler(Object o) {
        this.o = o;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(o,args);
    }
}

调用

Proxy.newProxyInstance(Target.class.getClassLoader(), Target.class.getInterfaces(), new MyInvocationHandler(new T()));

Cglib动态代理

只需要cglib依赖。

解决没有接口的实现类的不修改源码增强。

定义

public class MyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        return methodProxy.invokeSuper(o,objects);
    }
}

调用

MyInterceptor myInterceptor = new MyInterceptor();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Target.class);
enhancer.setCallback(myInterceptor);
Target target = (Target) enhancer.create();

Spring

使用框架三步走:依赖,配置,使用。

IOC

只需要Beans,Core,Context,Expression,commons-logging五个依赖。

解决对象的创建交给第三方容器。

IOC本质

解决IOC的实现原理。

  1. 原生new代码到处写

  2. 使用工厂模式new代码提取到一起

  3. IOC是使用xml,反射,工厂模式【将所有配置的类存储到map集合】

基础配置

解决IOC配置的基本标签。

  1. <bean id="" class=""/>:配置id和全限定类名

  2. <bean name="">:配置别名获取bean

  3. <bean scope=”>:配置单例多例

  4. <bean lazy-init="">:配置懒加载【applicationContext才有效】

  5. <beans profile="环境名称">:指定环境

    1. 虚拟机:-Dspring.profiles.active=环境名称

    2. 设置环境变量:System.setProperty("spring.profiles.active","环境名称")

  6. <import resource="">:引入外部资源

  7. <alias>:起别名

Bean创建方式

  1. 构造方式实例化Bean。

  2. 工厂方式实例化Bean。

    1. <bean factory-bean="Bean的id" factory-method="工厂中的方法">:【普通工厂实例化Bean】

    2. <bean class="全限定类名" factory-method="工厂中的方法">:【静态工厂实例化Bean】

Bean初始化销毁

解决Bean在实例化之后的初始化的一个环节。

初始化方法:Bean实例化之后的初始化方法

销毁方法:Bean销毁之前的销毁方法【显示关闭调用销毁方法】

接口

  1. InitializingBean:Bean初始化接口

  2. DisposableBean:Bean销毁接口

配置文件

  1. <bean init-method="">:Bean初始化配置

  2. <bean destroy-method="">:Bean销毁配置

注解

  1. @PostConstruct:Bean初始化注解

  2. @PreDestroy:Bean销毁注解

获取IOC容器

解决IOC容器获取的方式。

  1. BeanFactory:最顶层接口【懒加载】

  2. DefaultListableBeanFactory:默认工厂实现

    1. XmlBeanDefinitionReader(DefaultListableBeanFactory);读取器

    2. read.loadBeanDefinition("bean.xml");读取文件

  3. new ClassPathXmlApplicationContext("bean.xml"):从类路径获取配置

  4. new FileSystemXmlApplicationContext("本地配置"):从磁盘回去配置

  5. new AnnotationConfigApplicationContext("配置类"):加载配置类

BeanFactory和ApplicationContext区别

  1. 叫法

    1. BeanFactory叫bean工厂

    2. ApplicationContext叫String容器

  2. 功能

    1. BeanFactory更底层

    2. ApplicationContext对监听,国际化等进行扩展

  3. Bean创建时机

    1. BeanFactory调用时加载

    2. ApplicationContext容器创建时加载

  4. 关系

    1. ApplicationContext继承Factory

    2. 还进行了扩展

getBean

解决从容器中获取Bena。

  1. 方式一:根据beanName获取【需要强转】

  2. 方式二:根据beanType获取【类型唯一】

  3. 方式三:根据beanName和beanType获取

FactoryBean【延迟加载】

  1. 实现该接口

  2. 调用get获取该实现类的时候,调用的是该类的getObject方法

其他标签使用

  1. p名称空间使用,可以在bean上p:name对name属性注入。

  2. null子标签可以代表属性的空值

  3. <>对属性中的特殊符号转义

  4. <![CDATA[]]>对内容中的特殊符号转义

命名空间

context命名空间

  1. <context:compont-scan base-package="包名"/>【@ComponentScan:扫描注解】

  2. <context:property-placeholder location="classpath:jdbc.properties"/>【@PropertySource:加载properties】

  3. ${jdbc.url}使用spring的EL表达式【@Value:使用基本数据】

aop命名空间

  1. <aop:aspectj-autoproxy/>【@EnableAspectJAutoProxy:使用aop注解】

tx命名空间

  1. <tx:annotation-driven transaction-manager="transactionManager"/>【@EnableTransactionManagement:开启事务注解支持】

命名空间解析

  1. handlerMappings:解析器存储,在/META-INF/spring.handlers文件中

  2. 命名空间都包含在/META-INF/spring.schemas

  3. 根据不同的namespaceHandler去解析各自的配置信息。

  4. 对应框架的BeanDefinitionParser的paeser解析

    1. 要么注册BeanDefinition

    2. 要么BeanPostProcessor加入Bean

自定义命名空间

  1. 确定命名空间,schema虚拟路径,标签名称

  2. 编写约束文件

  3. /META-INF/约束映射文件spring.schemas和处理器映射文件spring.handlers

  4. NamespaceHandler处理器,并在init方法注册BeanDefinitionParser

  5. BeanDefinitionParser解析器,并在parse注册BeanPostProcessor

  6. 编写BeanPostProcessor

  7. 引入约束文件【引入约束的命名空间和命名空间的地址文件。】

  8. 编写自定义标签

DI

解决IOC容器中的Bean之间的关系,以及基本属性注入。

配置注入

  1. set注入Bean:<property name="属性" ref="Bean的id"/>

  2. set注入值:<property name="属性" value="值"/>

  3. construct注入Bean:<construct-arg name="形参" ref="Bean的id"/>

  4. construct注入Bean:<construct-arg name="形参" value="值"/>

1. list:\\<value>aaa\</value>\</list>
    <list>
	    <value>aaa</value>
    	<ref bean="id值"/>
    </list>
2. map
    <map>
    	<entry key="k1" value-ref="id值"/>
    </map>
3. properties
    <props>
    	<prop key="k1">string</prop>
	</props>

自动装配

配置文件

  1. <bean autowire="byType">:根据set注入的名称

  2. <bean autowire="byName">:根据set注入的参数类型

  3. <bean autowire="byName">:根据构造注入

Bean

Bean实例化流程

解决Bean实例化的整个过程

  1. Spring容器初始化

  2. 【读取配置文件】

  3. 执行一系列的BeanFactoryPostProcessor实现类,【处理注解配置】【Bean工厂后置处理器】

  4. 【将配置文件封装成BeanDefinitionMap集合】

  5. Spring再遍历BeanDefinitionMap集合使用反射创建Bean实例对象

  6. 调用构造方法

  7. 属性注入【DI】

  8. Aware接口

  9. postProcessBeforeInitalization【Bean后置处理器Before方法】

  10. InitializingBean初始化接口

  11. init-method初始化方法

  12. postProcessAfterInitalization【Bean后置处理器After方法】

  13. 创建号的Bean对象存储到singletonObjects的Map集合中

  14. getBean方法就是从singletonObjects的Map集合中获取对象

BeanFactoryPostProcessor

解决动态注册和修改BeanDefinition的扩展点。

使用

  1. 实现BeanFactoryPostProcessor接口

  2. 把实现类交给Spring容器【Spring自动调用该接口方法】

  3. 修改BeanDefinition

    1. getBeanDefinition:获取BeanDefinition

    2. BeanDefinition的方法直接修改【修改就生效】

  4. 注册BeanDefinition

    1. 创建RootBeanDefinition

    2. ConfigurableListableBeanFactory向下转型DefaultListableBeanFactory并调用registerBeanDefinition

    3. 注册BeanDefinition。

专门注册BeanDefinition接口

  1. BeanDefinitionRegistryPostProcessor接口继承BeanFactoryPostProcessor

  2. postProcessBeanDefinitionRegistry方法专门注册BeanDefinition

BeanPostProcessor

实例化之后和初始化之后的两个扩展点。

解决动态修改Bean。

使用

  1. 实现BeanPostProcessor接口

  2. 把实现类交给Spring容器【Spring自动调用该接口方法】

  3. postProcessBeforeInitalization:紧接着实例化执行

  4. postProcessAfterInitalization:在init初始化之后执行

Bean生命周期

解决Bean实例化之后,到最后存储到SingletonObjects中。

  1. 实例化阶段

    1. 单例判断

    2. 延迟判断

    3. FactoryBean判断

    4. 【实例化】

  2. 初始化阶段

    1. 属性填充,依赖注入

      1. 普通属性直接注入

      2. 单向对象注入,先创建被注入对象Bean实例

      3. 双向对象注入,循环依赖

    2. 执行Aware【根据接口注入对象】

    3. 执行BeanPostProcessor的Before

    4. 执行InitializingBean初始化

    5. 执行自定义初始化

    6. 执行BeanPostProcessor的After

循环依赖

解决属性注入先实例化所需bean,现在用引用代替。Spring使用三级缓存解决。

  1. singletonObjects:单例池【对象没引用其他Bean】

  2. earlySingletonObjects:早期单例池【对象引用其他Bean,且被引用】

  3. ObjectFactory:对象工厂【对象引用其他Bean,但是没被引用】

执行顺序

  1. 实例化Bean放到三级缓存。

  2. 查找所需依赖,三个缓存都没有,去BeanDefinition实例化。

  3. 查找所需依赖,三级缓存有,将三级缓存的bean移动到二级缓存,完成三级缓存中满足属性注入的Bean加入到单例池。

  4. 查找所需依赖,一级二级缓存有就直接加入到单例池。

Aware接口

解决Bean对象使用相关的API,由Spring容器自动注入。

  1. ServletContextAware:回调方法注入ServletContext【web环境才生效】

  2. BeanFactoryAware:回调方法注入BeanFactory

  3. BeanNameAware:回调方法注入BeanName

  4. ApplicationContextAware:回调方法注入ApplicationContext

注解配置

解决有关注解配置的使用。

特殊配置

2.5时代

  1. <context:compont-scan base-package="包名"/>【扫描注解配置】

  2. <context:property-placeholder location=""/>【加载properties配置】

3.0时代

  1. @ComponentScan:扫描注解

  2. @PropertySource:加载properties

  3. @Configuration:代表application.xml配置文件【具有@Component作用】

  4. @Import:引入其他配置类

  5. @Primary:放在@Component或@Bean上,@Autowire获取Bean优先级更高

  6. @Profile:放在@Component或@Bean上,表示指定环境下生效

  7. 【@Profile指定环境,第一虚拟机参数,第二环境变量System】

IOC配置

  1. @Component:标识类,配置Bean

    1. @Repository

    2. @Service

    3. @Controller

  2. @Scope:标识bean类,作用范围

  3. @Lazy:标识bean类,懒加载

  4. @PostConstruct:标识bean类的方法,初始化方法

  5. @PreDestroy:标识bean类的方法,销毁方法

  6. @Bean:标识bean类的方法,自定义Bean【默认方法名称】【@Autowire可以省略】

DI配置

解决属性注入,有set走set,没有就暴力反射。

  1. @Value:注入普通数据

  2. @Autowire:根据byType自动装配

  3. @Qualifier:配合@Autowire再根据byName自动装配

  4. @Resource:根据byType或byName自动装配

AOP

只需要aop和aspectjweaver依赖。【aop是一个思想,aspectjweaver是实现】

解决对使用动态代理某一个Bean进行增强。

AOP本质

本质就是在Spring容器,Bean后置处理器使用的动态代理。

AOP相关词汇

  1. Target目标对象

  2. Proxy代理对象

  3. Joinpoint连接点

  4. Pointcut切入点

  5. Advice通知

  6. Aspect切面

  7. Weaving织入

使用思路

  1. 增强类书写

  2. 哪个包类方法需要增强

  3. 对目标方法那些通知进行增强

切入点表达式

语法

execution([访问修饰符][返回类型][全限定类名][方法名称]([参数列表]))
    
    1.权限修饰符:【可以省略】
    2.返回类型:*代表任意字符Str*
    3.全限定类名:*.代表任意字符,*..代表所有的包
    4.方法名称:*代表任意字符,
    5.参数列表:*代表任意类型,..代表任意类型任意个数
    
    通配符
    

通知

  1. 前置通知:@Before:前置通知

  2. 返回通知:@AfterReturning:返回通知【Returning属性:获取返回值】

  3. 异常通知:@AfterThrowing:异常通知【Throwing属性:获取异常信息】【针对目标】

  4. 最终通知:@After:最终通知

  5. 环绕通知:@Around:环绕【ProceedingJoinPoint:调用被代理方法】

环绕通知有限执行。

XML配置aspect

解决指定通知类的方法作为通知。

  1. 配置目标类Bean

  2. 配置通知类Bean

  3. aop切面配置

    1. pointcut切入点表达式

    2. aspect代理类的通知方法,切入点绑定

XML配置advice

解决实现了advice接口的类作为通知类。

  1. 配置目标类Bean

  2. 配置通知类Bean

  3. 实现了advice接口的通知类绑定一个advice配置

  4. aop切面配置

    1. pointcut切入点表达式

    2. advice的配置,切入点绑定

注解配置AOP

  1. 开启注解支持:aop:aspectj-autoproxy配置或@EnableAspectJAutoProxy

  2. 配置目标类Bean

  3. 配置通知类Bean

  4. @Aspect:切面配置

    1. @PointCut:切入点

    2. 通知注解

  5. @Order【值越小越先执行】

AOP声明式事务

使用

xml方式

  1. <tx:advice>配置advice就行

  2. 目标方法配置属性

注解方式

  1. @TransactionManager就不用配置advice和切面

  2. 加上<tx:annotation-driven transaction-manager="transactionManager"/>【自带AOP支持】

纯注解

  1. @TransactionManager就不用配置advice和切面

  2. @EnableTransactionManagement:开启事务支持【自带AOP支持】

核心三个类
  1. PlatformTransactionManager接口:事务管理器

  2. TransactionDefinition:事务设置

  3. TransactionStatus:事务状态【提交回滚】

JdbcTemplate

解决jdbc简单封装实现。

  1. 将JdbcTemplate中放入dataSource就行了。

整合JUnit

只需要spring-test依赖。

Junit4
  1. @RunWith(SpringJUnit4ClassRunner.class)

  2. @ContextConfiguration("classpath:spring.xml")

Junit5
  1. @ExtendWith(SpringExtension.class)

  2. @ContextConfiguration("classpath:spring.xml")

  3. 复合注解@SpringJUnitConfig(locations="classpath:spring.xml")

webFlux

Servlet3.1的核心api是Reactor,异步非阻塞。

整合框架

Mybatis

解决其他框架整合。

XML配置整合

  1. 不需要其他命名空间:Mybatis

  2. 需要其他命名空间:Dubbo

XML整合Mybatis

需要mybati-spring整合包,spring-jdbc和tx依赖。

  1. 注入Bean

    1. SqlSessionFactory

    2. MapperScannerConfig

  2. 书写Mapper

  3. 书写Mapper.xml

Mybatis整合原理

一共四个核心类

  1. SqlSessionFactoryBean:提供SqlSessionFactory

  2. MapperScannerConfigurer:扫描指定mapper注册BeanDefinition

  3. MapperFactoryBean:获得指定mapper是调用getObject方法

  4. ClassPathMapperScanner:definition.setAutowireMode【向MapperFactory自动注入SqlSessionFactory】

注解整合Mybatis

  1. 注册SsqlSessionFactory的bean对象

  2. @MapperScan:扫描Mapper接口

web

原生整合

  1. web的三大组件

  2. SerlvetContextLisener监听器执行容器的创建

  3. context-param配置上要加载的spring配置文件

  4. WebApplicationContextUtils.getWebApplicationContext

spring-web依赖整合

  1. 监听器由整合包提供

  2. 工具类由整合包提供

SpringMVC

只需要spring-webmvc依赖,javax-servlet-api:3.1.0【provided】不参与打包。

解决三个事情,servlet公共部分抽取,setvlet根据业务分Controller,servlet接入spring容器。

所有操作

web配置文件

  1. 前端控制器ServletDispatcher

  2. 乱码过滤器CharacterEncodingFilter

  3. 请求方式过滤器HiddenHttpMethodFilter

mvc配置文件

  1. mvc注解驱动【添加】

  2. 视图控制器

  3. 默认servlet

  4. 拦截器interceptor

  5. 上传解析器multipartResolver

  6. 异常处理器解析器SimpleMappingExceptionResolver

  7. 视图解析器viewResolver

重要组件执行顺序

MVC:模型,视图,控制器。

  1. 前端控制器获取请求

  2. 处理器映射器解析地址【处理器映射器】

  3. 返回处理器执行链

  4. 处理器适配器找到对应的处理器【处理器适配器】

  5. 处理器执行【处理器】

  6. 处理器返回结果数据

  7. 处理器适配器返回结果数据

  8. 视图解析器解析视图【视图解析器】

  9. 视图解析器返回视图对象

  10. 前端控制器响应

获取请求参数

原生获取

  1. request.getParam获取单个参数

  2. request.getParams获取多个参数

MVC获取参数

原生方法

  1. Aware获取原生API获取请求参数

直接封装

  1. 保证名称一致,字符串获取多值时的格式:a,b,c

  2. 保证名称一致,数组获取多值的格式:[a,b,c]

对象接收参数

  1. 保证属性名称和参数一致。

获取请求信息相关注解

  1. @RequestParam注解,封装请求参数【别名,集合不创建对象接收参数】

  2. @RequestHeader注解,封装请求头

  3. @CookieValue注解,封装cookie信息

三个注解都有这三个属性
    1. name:映射名称
    2. required:必须赋值【默认】
    3. defaultValue:默认值

解决乱码

处理要求:处理乱码需要在获取参数之前设置请求编码。

  1. get乱码:属于tomcat乱码,server.xml配置文件设置urlEncoding编码解决。

  2. post乱码:在前端控制器之前执行编码。

    1. 过滤器解决CharacterEncodingFilter处理器

    2. 初始化参数:设置请求编码encoding

    3. 设置【响应】编码:设置forceResponseEncoding为true就可以了

结果数据

  1. 原生ServletAPI向request域中存值。

  2. ModelAndView【基本对象】

    1. addObject:添加共享数据

    2. setViewName:跳转页面

  3. Model【Aware参数注入】

    1. addAttribute:添加共享数据

  4. Map【Aware参数注入】

    1. put:添加共享数据

  5. ModelMap【Aware参数注入】

    1. addAttribute:向request中设置数据

【BindingAwareModelMap是根本实现类】

MVC注解驱动

需要注解驱动的情况<mvc:annotation-driven />

  1. 视图控制器:<mvc:view-controller path="/" view-name="success"/>【请求地址和视图的映射,走视图解析器】

  2. 默认的servlet:<mvc:default-servlet-handler/>【处理静态资源】

  3. java对象转成json:HttpMessageConvertor

报文信息转换器

HttpMessageConverter

  1. @RequestBody:请求体

  2. @ResponseBody:响应体【返回值转换成响应体】

  3. RequestEntiry:请求报文对象

  4. ResponseEntiry:响应报文对象

Json格式转换支持

只需要jackson-(databind,core,annotations)依赖。

  1. <mvc:annotation-driven />

  2. @ResponseBody

上传下载

下载:使用ResponseEntiry

    bytes = 文件读取的字节数组。
    headers = new HttpHeaders().add("Context-Disposition","attachment;filename=1.jpg")
    statusCode = HttpStatus.OK。
return new ResponseEntiry(bytes,headers,statusCode)

上传:【multipartResolver自动注入到Spring容器中】

只需要commons-(io和fileupload)两个依赖。

  1. 发送form表单,method=post请求,encType=multipart/form-data

  2. 表单项type=file,name表单项名

  3. 配置文件上传解析器:<bean id="multipartResolver" class="org.spingframework.multipart.commons.CommonsMultipartResolver"/>

  4. MultipartFile【参数封装】

  5. MultipartFile.transferTo:转存方法。

前端控制器

xml配置

dispatcherServlet默认配置

<load-on-startup>1
springMVC的配置文件【默认】
WEB-INF下的【名称】<servlet-name>-servlet.xml

dispatcherServlet扩展配置

<init-param>
param-name:contextConfigLocation
param-value:classpath:springMVC.xml
<load-on-startup>1

前端控制器处理/路径:表示的路径是除了JSP之外的处理,/*是所有处理。

映射器

使用

使用在类上

  1. 给Controller处理器方法加上前缀。

使用在方法上

@RequestMapping("/hello")
public String hello(){
    System.out.println("hello请求进入");
    return "hello";
}

@RequestMapping

  1. value(path):映射请求地址

    1. 可以是数组多个请求映射

  2. method:映射请求方式

    1. 可以是数组多个请求方式

  3. params:映射请求参数

    1. param:必须携带该参数

    2. !param:必须不携带该参数

    3. param=value:该参数一定定于该值

    4. param!=value:该参数不等于该值

  4. headers:映射请求头

    1. header:必须携带该参数

    2. !header:必须不携带该参数

    3. header=value:该参数一定定于该值

    4. header!=value:该参数不等于该值

@RequestMapping派生注解

  1. @GetMapping

  2. @PosyMapping

ant风格路径

RequestMapping的映射路径。

  1. ?任意一个字符

  2. *任意0-多个字符

  3. **任意0-多层级目录

rest风格路径

  1. 路径传参

  2. /{id}:映射接收路径

  3. @PathVariable("id")取出参数

rest风格请求方式

  1. 页面请求:<input type="hidden" name="_method" value="put"/>

  2. 配置隐藏请求方式过滤器:HiddenHttpMethodFilter

  3. 【必须配置在乱码之后,因为此处获取了_method请求参数】

拦截器

使用

拦截器实现类

  1. HandlerInterceptor接口的实现类

  2. preHandler:处理之前拦截

  3. postHandler:处理之后加强

  4. afterComplation:视图渲染之后方法

配置拦截器

  1. <mvc:interceptors>配置拦截器

  2. <bean class=""/>:对所有请求拦截【通过类路径创建Bean】

  3. <ref bean=""/>:对所有请求拦截【使用IOC中的对象】

  4. <mvc:interceptor>:配置指定路径

    1. <bean class=""/>:对指定请求拦截【通过类路径创建Bean】

    2. <ref bean=""/>:对指定请求拦截【使用IOC中的对象】

    3. <mvc:mapping path=""/>:包含指定路径

    4. <mvc:exclude-mapping path=""/>:排除指定路径

执行顺序

正常执行

  1. 按配置顺序一顺执行完毕两个preHandler

  2. 处理器处理请求

  3. 按配置顺序反向执行两个postHandler

  4. 按配置顺序反向执行两个afterComplation

第二个拦截器拦截

  1. 按配置顺序一顺执行完毕两个preHandler

  2. 处理器和postHandler都【不执行】

  3. 执行第一个afterComplation

异常处理器

HandlerExceptionResolver接口实现类

  1. DefaultHandlerExceptionResolver【mvc默认异常处理实现】

  2. SimpleMappingExceptionResolver【自定义异常处理】

配置方式

  1. SimpleMappingExceptionResolver配置bean

  2. 属性

  3. exceptionMappings:K是异常,V是新的视图

  4. exceptionAttribute:向请求域中存储错误信息

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<property name="exceptionMappings">
    	<props>
    		<prop key="异常类">视图【过视图解析器】</prop>
        </props>
    </property>
    <property name="exceptionAttribute" value="ex"/>【异常信息key为ex存放到request域中】
</bean>

注解方式

  1. @ControllererAdvice:标志类是异常处理组件

  2. @ExceptionHandler(异常类):处理哪一个异常

  3. 方法上放Exception和Model

@ControllerAdvice
public class MyExceptionController{
    @ExceptionHandler(异常类)
    public String testException(Exception ex,Model model){
        model.setAttribute("ex",ex);
        return "视图【过视图解析器】";
    }
}

适配器

控制器

  1. 使用在控制器类上:@Controller

  2. 使用在控制器类上:@RestController等同于给每个方法【额外加上@ResponseBody】

视图解析器

解析器种类

  1. 视图解析器:【JSTL:InternalResourceView】,ThymeleafView。

  2. 转发:InternalResourceView【forward:/testView】Servlet

  3. 重定向:RedirectView【Redirect:/testView】Servlet

配置JSP视图解析器

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!-- 视图前缀 -->
    <property name="prefix" value="/WEB-INF/templates/"/>
    <!-- 视图后缀 -->
    <property name="suffix" value=".html"/>
</bean>

配置thymeleaf

只需要thymeleaf-spring5依赖。

<!-- 配置Thymeleaf视图解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
    <property name="order" value="1"/><!--视图优先级-->
    <property name="characterEncoding" value="UTF-8"/><!--编码-->
    <property name="templateEngine"><!--模板-->
        <bean class="org.thymeleaf.spring5.SpringTemplateEngine"><!--spring模板-->
            <property name="templateResolver"><!--模板解析器-->
                <!--spring资源模板解析器-->
                <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                    <!-- 视图前缀 -->
                    <property name="prefix" value="/WEB-INF/templates/"/>
                    <!-- 视图后缀 -->
                    <property name="suffix" value=".html"/>
                    <property name="templateMode" value="HTML5"/><!--模板模式-->
                    <property name="characterEncoding" value="UTF-8"/><!--编码-->
                </bean>
            </property>
        </bean>
    </property>
</bean>

html使用thymeleaf

  1. <html lang="en" xmlns:th="http://www.thymeleaf.org">:引入约束

th使用

  1. <a th:href="@{/hello}">访问hello页面</a>:相对请求路径

  2. servlet(username='admin',password=123456):设置参数

  3. 可以使用th的EL表达式。

欢迎页面

<welcom-file-list>
	<welcome-file>index.html\<welcome-file>
</welcom-file-list>

页面异常

  1. 400,请求参数不匹配。

  2. 404,请求路径不匹配。

  3. 405,请求方式不匹配。

注解配置

注解配置本质

  1. Servlet3.0会自动查找ServletContainerInitializer接口的实现类

  2. Spring实现ServletContainerInitializer接口的类SpringServletContainerInitializer

  3. SpringServletContainerInitializer查找WebApplicationInitializer接口的实现类

  4. Spring3.2提供WebApplicationInitializer的实现抽象类AbstractAnnotationConfigDispatcherServletInitializer

web配置类使用

  1. 实现AbstractAnnotationConfigDispatcherServletInitializer

  2. getRootConfigClasses:设置Spring配置

  3. getServletConfigClasses:设置SpringMVC配置

  4. getServletMappings:配置前端控制器路径

  5. getServletFilters:设置过滤器

mvc配置类使用

  1. 实现WebMvcConfigurer

  2. 扫描组件:@ComponentScan("com.ycl")

  3. 注解驱动:@EnableWebMvc

  4. 视图解析器:ViewResolver【Bean】

  5. 视图控制器:addViewControllers

  6. 默认servlet:configureDefaultServletHandling.enable();

  7. 文件上传解析器:MultipartResolver【Bean】

  8. 拦截器:addInterceptors

  9. 异常处理:configureHandlerExceptionResolvers【bean】

Mybatis

只需要mybatis和数据区驱动。

调用方式

  1. 两个配置文件使用selectOne发送请求

  2. 两个配置文件加上接口使用getMapper获取代理类,调用对应方法执行

全局配置文件

解决mybatis核心配置文件。约束在官网拉取。

  1. Conguration接口

基本实现

  1. 环境:事务处理器和数据源

  2. 找到映射文件

全局配置

  1. propertis:引入外部资源【配合${}取数据】

    1. 优先级:1.方法参数。

    2. 优先级:2.外部文件引入。

    3. 优先级:3.标签里。】

  2. settings:全局设置

    1. mapUnderscoreToCamelCase:驼峰映射

    2. jdbcTypeForNull:设置全局空值jdbc标识

    3. lazyLoadingEnable:全局开启

    4. aggressiveLazyLoading:关闭任何方法触发

    5. cacheEnabled:全局缓存

  3. typeAliases:给javaType起别名

    1. 1.直接指定。

    2. 2.包指定,别名为类名首字母小写或@Alias

  4. typeHandler:类型处理器【源码】

  5. plugins:拦截核心步骤【源码】

    1. 拦截Excutor。

    2. 拦截ParamenterHandler。

    3. 拦截StatementHandler。

    4. 拦截ResultSetHandler。

  6. environments:环境配置

    1. 事务管理器

      1. JDBC:jdbc的事务

      2. MANAGED:容器事务

    2. 数据源

      1. UNPOOL:不用池

      2. POOL:使用池

      3. JNDI:使用外部配置

  7. databaseIdProvider:开启多数据库支持

  8. mappers:找映射文件或注解

    1. resource

      1. url是全限定资源定位符

      2. class是接口类的全限定类名。

    2. package包下的所有映射文件或CRUD注解

  9. objectFactory:对象工厂【创建结果对象时,通过该工厂实例化】

Mapper映射文件

解决mybatis核心配置文件。约束在官网拉取。

基本实现

  1. mapper标注命名空间

  2. CRUD的SQL语句标签

映射配置

  1. CRUD【@Select,@Insert,@Update,@Delete】

    1. #{}是预编译参数

    2. flushCache清除一级二级缓存

    3. timeout超时时间

    4. statementType选择语句类型【非预编译,预编译,存储过程】

    5. databaseId数据库厂商标识

  2. resultMap:结果集映射

  3. sql:抽取公共SQL

  4. cache:开启二级缓存

  5. cache-ref:引用外部缓存配置

增加修改

  1. useCeneratedKeys:增加修改时生成值

  2. keyProperty:主键值填充到属性

  3. selectKey:增加修改【子标签】

    1. keyProperty:替换增加修改字段值

    2. resultType:返回值类型

    3. order:增加修改之前或之后执行

查询

  1. resultType封装结果集类型

  2. resultMap引用外部的resultMap标签

  3. useCache结果给二级缓存保存,

  4. fetchSize返回结果条数限定建议

  5. resultSetType结果集指针策略

typeHandler

参数处理

单个参数

  1. 直接取出:id=#{id}

多个参数

  1. 多个参数以arg0和param1作为key

  2. 参数起别名给arg0进行替换

POJO

  1. 属性名取值

Map

  1. key取值

Collection

  1. list和map都可以用collection作为key

  2. list还可以用list作为key

数组

  1. 数组以array作为key

#和$

  1. javaType

  2. jdbcType

  3. mode:存储过程

  4. numericScale:数值范围

  5. resultMap

  6. typeHandler

  7. jdbcTypeName

  8. expression:未来扩展

结果处理

List

  1. resultType类型为元素

POJO

  1. resultType类型是类

Map

  1. Map的key是列名,value是对应值【此处和OPJO相似】

  2. resultType是map类型

Map

  1. Map的key是主键,value是对应对象

  2. resultType类型为元素

  3. @MapKey("id"):标识Map集合的key

resultMap

映射类

    <resultMap id="userMap" type="user">
        <id property="" column=""/>
        <result property="" column=""/>
    </resultMap>

包含类属性

    <resultMap id="userMap" type="user">
        <id property="" column=""/>
        <result property="" column=""/>
        <result property="" column=""/>【属性类的属性表示】
    </resultMap>

多表联查

一对一关联对象

    <resultMap id="userMap" type="user">
        <id property="" column=""/>
        <result property="" column=""/>
        <association property="属性" javaType="属性类型">
            <id property="" column=""/>
            <result property="" column=""/>
        </association>
    </resultMap>

一对一分步查询

    <resultMap id="userMap" type="user">
        <id property="" column=""/>
        <result property="" column=""/>
        <association property="属性" select="关联查询的命名空间+id"
        	column="列值传递"/>
    </resultMap>【分步查询是简单查询】

一对多关联查询

    <resultMap id="userMap" type="user">
        <id property="" column=""/>
        <result property="" column=""/>
        <collection property="" ofType="">
            <id property="" column=""/>
            <result property="" column=""/>
        </collection>
    </resultMap>

一对多分步查询

<resultMap id="userMap" type="user">
    <id property="" column=""/>
    <result property="" column=""/>
    <collection property="属性" select="关联查询的命名空间+id"
        	column="列值传递"/>
</resultMap>【分步查询是简单查询】

鉴别器

<discriminator javaType="">
    <case value=""></case>
</discriminator>【满足条件才会加上规则】

延迟加载

  1. lazyLoadingEnable:全局开启

  2. aggressiveLazyLoading:关闭任何方法触发

  3. fetch="lazy"局部懒加载

多值传递

  1. column="{deptId=id}"

动态SQL:OGNL

if

  1. <if test=' '></if>

where

  1. <where></where>包裹相当于where 1=1;

set

  1. <set></set>包裹相当于去除尾部逗号

trim

  1. <trim><trim>解决前缀和后缀规则

choose(when,otherwise)

  1. <choose></choose>

  2. <when test=""></when>

  3. <otherwise></otherwise>

foreach

  1. collection:集合

  2. item:每一个遍历的元素

  3. separator:每一个元素之间的分隔符

  4. open:遍历结果开始字符

  5. close:遍历结果结束字符

  6. index:遍历List的时候是下标

  7. 遍历map

    1. index:是key值

    2. item:是value值

批量插入

  1. 遍历多条sql语句【allowmultiqueryies=true】

  2. 遍历values的值

内置参数

  1. _parameter:

    1. 单个参数,这个内置参数就是它

    2. 多个参数,这个内置参数就是所有参数的map集合

  2. _databaseId:

    1. 表示当前数据库

    2. 起别名之后,代表当前数据库的别名

变量绑定

参数拼接绑定
	<bind name="_last" value="'%'+last+'%'"/>

缓存

一级缓存失效

  1. 不是同一个SqlSession

  2. 同一个SqlSession,查询条件不同

  3. 同一个SqlSession,执行了一次操作

  4. 同一个SqlSession,清除缓存了。【clearCache方法】

二级缓存数据来源

  1. 一级缓存关闭,就会存入二级缓存

二级缓存失效

  1. cacheEnabled:关闭二级缓存

  2. useCache:关闭SQL语句的二级缓存

  3. flushCache:操作SQL刷新缓存

二级缓存查询顺序

  1. 二级缓存

  2. 一级缓存

  3. 查询数据库

二级缓存开启

  1. cacheEnabled:全局缓存

  2. <cache/>:配置二级缓存

整合二级缓存

只需要encache和mybatis-encache依赖

  1. <cache type="配置上Encache就行"/>

逆向工程

只需要mybatis-generator-core依赖。MyBatis Generator Core – MyBatis Generator Quick Start Guide

运行原理

SqlSessionFactoryBuilder的build方法返回DefaultSqlSessionFactory

  1. 结合被解析对象返回XMLConfigBuilder

  2. 解析对象返回Configuration对象

    1. CRUD标签解析:MappedStatements

    2. 接口信息:mapperRegistry:

  3. 执行build方法返回SqlSessionFactory

    1. 调用DefaultSqlSessionFactory(Configuration)

build.openSession()返回DefaultSqlSession对象

  1. 创建执行器this.configuration.newExecutor(tx, execType)

    1. 缓存执行器包装

    2. excutor拦截器链【】【】【】

  2. 创建SqlSession对象new DefaultSqlSession(this.configuration, executor, autoCommit)

  3. 【】Executor的execType执行器类型取值【】

    1. simple:简单

    2. REUSE:重用

    3. BATCH:批量

sqlSession.getMapper(UserMapper.class)

  1. mapperRegistry根据接口类型获取MapperProxyFactory

  2. 创建MapperProxy对象

  3. 返回动态代理MapperProxy

mapper.findAll()

  1. 判断CRUD,判断返回结果集

  2. 参数转换成SQL参数

  3. 获取statement语句

  4. SQL绑定成为完整句子

  5. Query执行【二级缓存】

  6. doQuery

    1. 创建StatementHandler

      1. 创建RoutingStatementHandler

        1. paramer拦截器链【】【】【】

        2. resultSet拦截器链【】【】【】

      2. Statement拦截器链【】【】【】

    2. 处理预编译SQL语句

    3. 执行SQL语句

插件InterceptorChain

框架调用拦截器链原理

  1. InterceptorChain遍历Interceptor

  2. 执行Interceptor的plugin(四个处理器对象)

自定义插件

  1. 实现Interceptor接口

Interceptor接口方法

plugin方法

return Plugin.wrap(target, this)
    1. 获取签名映射
    	1. 获取Intercepts注解
    	2. 获取签名每一项Signature
    	3. 遍历每一个标签,Map<Class<?>, Set<Method>>
    		【签名中所有的类型和方法都封装到Map中】
    2. 获取target类型
    3. 获取所有接口
    		【目标类是所有接口和所有签名进行匹配】
    4. 生成代理对象【匹配上生成增强对象,否则直接返回】
    		【给适配方法执行】
    this.interceptor.intercept(new Invocation(this.target, method, args))
    调用当前的intercept方法

intercept方法

	Invocation的proceed():是调用原始方法
使用

拦截器类书写

@Intercepts(@Signature(type = StatementHandler.class,method ="batch",args = {}))
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object proceed = invocation.proceed();//这里做增强
        return proceed;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }
}

配置拦截器

    <plugins>
        <plugin interceptor="com.ycl.interceptor.MyInterceptor"></plugin>
    </plugins>

多个插件

  1. 目标方法在intercept方法中嵌套。

分页

只需要pagehelper和jsqlparser两个依赖。

  1. 配置中添加拦截器PageInterceptor

调用

  1. 原生API:SqlSession(new RowBounds(0,10))【将RowBounds传到指定参数位置】

  2. mapper方式一:查询之前使用PageHelper.startPage(0,10)

  3. mapper方式二:查询之前使用PageHelper.offsetPage(0,10)

  4. 注解不需要xml处理:@Param("pageNum") pageNum和@Param("pageSize") pageSize

  5. 【只要请求参数中能取到这两个值就可以】

【PageInfo包装处理分页结果】

执行器

  1. 批量保存:BatchExcutor会让数据库保存预编译保存语句,修改参数值进行保存。

  2. Spring中使用批量操作,注册SqlSessionTemplate【并且指定Excutor】

存储过程

解决多个sql语句的集合。

  1. 调用statementType="CALLABLE"

  2. 语法:{call 存储函数(#{名称,mode=,jdbcType=})}

TypeHandler

定义

  1. 实现TypeHandler接口或继承BaseTypeHandler类

  2. @MapperType:定义java类型

  3. @MapperJdbcType:定义jdbc类型

使用

  1. 使用方式一:自定义结果集,参数处理的时候【resultMap和#{id,typeHandler=xxxx}】

  2. 使用方式二:全局配置【handler使用类型处理器,javaType是某个类型时候使用】

MybatisPlus

只需要mybatisplus依赖。内部包含mybatis和mybatis-spring依赖。

Mybatis3.5.0之后就不支持GlobalConfiguration了,支持yum】

使用

  1. 前提条件mybatis和spring整合完成。

  2. 将SqlSessionFactoryBean修改成MybatisSqlSessionFactoryBean

BaseMapper

  1. Mapper接口继承BaseMapper<javaBean>接口

  2. 可以调用BaseMapper中的方法

方法

  1. 【增加】

  2. insert:非空字段才会出现在sql语句中

  3. insertAllColumn:所有的字段都会出现在sql语句中

  4. 【修改】

  5. updatteById:非空字段才会出现在sql语句的修改字段中

  6. updateAllColumnById:所有的字段都会出现在sql语句修改字段中

  7. 【查询】

  8. selectById:传入序列化类型的id,id作为查询条件

  9. selectOne:传入一个对象,非空字段作为条件

  10. selectBatchIds:传入collection的id集合,id作为枚举查询条件

  11. selectByMap:传入map集合,key=value作为条件

  12. selectPage:传入的RowRounds和wrapper条件。逻辑分页查询

  13. 【删除】

  14. deleteById:传入序列化类型的id,id作为条件

  15. deleteByMap:传入map集合,key=value作为条件

  16. deleteBatchIds:传入collection的id集合,id作为枚举查询条件

条件构造器

使用数据库的字段而不是java属性。EntityWrapper类

结构

  1. wrapper和AbstractWrapper【抽象父类】

  2. UpdateWrapper【查询】【删除】

  3. QueryWrapper【修改】

  4. 【三元素:condition,column,param】

  5. AbstractLambdaWrapper

    1. LambdaUpdateWrapper

    2. LambdaQueryWrapper

方式一

  1. QueryWrapper qw= new QueryWrapper();

  2. qw.eq();

  3. 【原始方式】

方式二

  1. QueryWrapper<User> qw= new QueryWrapper();

  2. qw.lambda().eq();

  3. 【使用Lambda表达式】

方式三

  1. LambdaQueryWrapper<User> lqw= new LambdaQueryWrapper();

  2. lqw.eq();

  3. 【使用Lambda表达式】

注解

  1. @TableId:主键策略IdType【value和列名一致】

    1. AUTO:自增

    2. NONE:用户自己输入

    3. INPUT:用户自己输入

    4. ASSIGN_ID:全局唯一ID,自动填充

    5. ASSIGN_UUID:全局唯一ID,自动填充

  2. @TableName:主要起别名

  3. @TableField:字段

    1. value:字段名映射

    2. exist:是否存在表字段

全局配置

核心API:GlobalConfiguration,加入到SqlSessionFactoryBean中。

  1. 驼峰映射:dbColumnUnderline

  2. 主键策略:idType

  3. 表的前缀:tablePrefix

其他使用

  1. 插入修改获取返回主键,直接获取就可以。

MP原理

  1. MapperProxy:代理对象

  2. SqlSessionFactory:会话工厂

  3. Configuration:配置信息

  4. MapperStatements:所有的SQL语句

BaseMapper的sql语句自动注入原理【AutoSqlInjector】

  1. 获取configuration中的sqlInjector配置(只能一个)

  2. AutoSqlInjector的injectSql方法所有增强分发

  3. 最终用addMappedStatement方法【可以在该环节增强】模仿作业

LogicSqlInjector逻辑删除

  1. 将LogicSqlInjector注入到SqlSessionFacotry中

  2. 并且配置逻辑删除值,删除标签和非删除标签

  3. @TableLogic逻辑删除delval表示逻辑删除标签

活动记录

ArtiveRecord

实体类去继承Model类就可以使用实体自己的CRUD操作

代码生成器

需要velocity-engine-core【模板引擎】或freemark依赖

可以生成domain,mapper,mapper映射,还可以生成service,controller。

  1. 全局配置:GlobalConfig

  2. 数据源配置:DataSourceConfig

  3. 策略配置:StrategyConfig

  4. 包名配置:PackageConfig

  5. 整合配置:AutoGenerator

  6. 执行:autoGenerator.execute();

示例

    public static void main(String[] args) {
        // 1.全局配置
        GlobalConfig config = new GlobalConfig();
        config.setActiveRecord(true)
                .setAuthor("YCL")
                .setOutputDir("D:\\mybatis-plus\\mpg\\src\\main\\java")
                .setFileOverride(true)
                .setIdType(IdType.AUTO)
                .setServiceName("%Service")
                .setBaseResultMap(true)
                .setBaseColumnList(true);

        // 2.设置数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL)
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUrl("jdbc:mysql:///jdbc_template?serverTimezone=Asia/Shanghai")
                .setUsername("root")
                .setPassword("root");

        // 3.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true)
                .setDbColumnUnderline(true)
                .setNaming(NamingStrategy.underline_to_camel)
//                .setTablePrefix("tb_")
                .setInclude("user");

        // 4.包名配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.ycl")
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("domain")
                .setXml("mapper");

        // 5.整合配置
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig);

        // 6.执行
        autoGenerator.execute();
    }

ServiceImpl

分页插件

分页插件:PaginationInteceptor

配置

  1. 将PaginationInteceptor插件注册

  2. 并且将插件传入到Configuration中

使用

  1. 创建一个page对象传入分页查询方法中【page是RowBounds的子类】

  2. page就可以直接获取所有page信息

其他插件

  1. 全表操作拦截

    <bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
        <property name="stopProceed" value="true"/>
    </bean>
  1. 慢SQL处理

    <bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor">
        <property name="format" value="true"/>
        <property name="maxTime" value="1"/>
    </bean>
  1. 乐观锁插件

必须使用@Version标记版本
    <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>

公共字段填充

元素据处理器接口MetaObjectHandler

  1. 注解填充@TableFile(fill=FieldFill.INSERT)

  2. 自定义公共字段填充器MetaObjectHandler子类

  3. MP全局配置注入填充器

MybatisX插件

  1. MybatisX代码生成器

  2. MybatisX快速添加CRUD

Maven

安装配置

Mvaen工具也可以叫做软件的安装配置。

安装

  1. Maven是apache的一个软件

配置

  1. 需要配置JAVA_HOME

  2. 设置自身的MAVEN_HOME

  3. mvn -v检测安装成功

目录

  1. bin:可执行命令

  2. boot:Maven类加载器框架

  3. conf:配置

  4. lib:Maven所需要的依赖支持

  5. LICENSE,NOTICE,README.tx:第三方软件介绍

功能配置

局部setting.xml放在repository同目录下

  1. 本地缓存位置【settings:<localRepository>】

  2. maven下载镜像

  3. maven选用jdk版本

镜像
    <mirror>
  		<id>aliyunmaven</id>
  		<mirrorOf>*</mirrorOf>
  		<name>阿里云公共仓库</name>
  		<url>https://maven.aliyun.com/repository/public</url>
	</mirror>
        或者
    <mirror>
  		<id>aliyunmaven</id>
		<mirrorOf>central</mirrorOf>
  		<name>阿里云公共仓库</name>   
  		<url>https://maven.aliyun.com/nexus/content/groups/public</url>
	</mirror>
JDK版本
    <profile>
		<id>jdk1.8</id>
		<activation>
		<activeByDefault>true</activeByDefault>
		<jdk>1.8</jdk>
	</activation>
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	</properties>
	</profile>

IDEA配置Maven

  1. maven软件位置

  2. settings.xml位置

  3. localRepository位置

工作原理

  1. pom.xml文件生成对应的pom对象

  2. 依赖管理模型,本地仓库管理jar包

  3. 私服仓库管理jar包

  4. 中央仓库下载jar包

  5. Maven构建生命周期插件

Maven作用

  1. 依赖管理工具

  2. 依赖构建工具

  3. 依赖分享工具

  4. 自动部署环节

1. 依赖管理工具
【原来】使用jar包依赖,将jar包放入WEB-INF/libs下面
【现在】
    1. Maven中央仓库下载到Maven本地仓库
    2. 本地仓库导入jar包
2. 依赖构建工具
	打包成jar包或war包
3. 依赖分享工具
    Nexus私服传递依赖
4. 自动部署环节
    从Maven推送到Git远程仓库
    持续集成Jenkins
    部署云原生kubernates到Docker实例

依赖管理工具

问题

  1. jar包不规范

  2. jar包之间依赖关系

  3. 必须存储到指定位置lib

GAVP属性

  1. groupId:com.公司.主业务.子业务

  2. artifactId:产品-模块

  3. version:主版本.次版本.修订号.里程碑版本【API修改,功能增强,bug修复,RELEASE】

  4. package:jar,war,pom【普通工程,web工程,父工程不打包】

依赖传递

  1. 直接依赖:配置文件中写了的依赖

  2. 间接依赖:配置文件的依赖,这个依赖还有依赖

  3. 依赖越直接层级越浅,优先级越高

  4. 依赖相同层级,前面配置的优先级高

  5. 同一个依赖配置,后面的依赖覆盖前面的依赖

  6. <optional>true</optional>隐藏依赖不被传递

  7. 排除依赖<exclusion>GAV</exclusion>

  8. 【模块只有打包之后才能用】

依赖范围

Scope

  1. 主程序

  2. 测试程序

  3. 是否参与打包

选项

  1. compile:主代码,测试,打包【log4j】

  2. test:只测试【junit】

  3. runtime:只打包【jdbc】

  4. provided:不打包【servlet-api】

模块聚合

  1. 不打包pom

  2. <modules>来引入聚合的项目【../项目名:同级目录】

继承依赖

  1. 模块继承<parent>GAV加上<relativePath>父工程pom文件</relativePath></parent>

  2. 父工程的<dependencyManager>管理依赖版本

属性管理

  1. 定义:<properties><spring.version>5.2.0.RELEASE</spring.version></properties>

  2. 使用:${spring.version}

  3. 还有:Maven内置属性,setting属性,java系统属性,env环境变量【mvn help:system】

properties使用POM配置属性

  1. <resources>\将pom配置属性也用到properties【指向指定的resources目录】【过滤拦截true】</resources>

多环境

  1. 定义:<profile>

    1. <id>dep_env

    2. <activation>true默认配置

  2. 使用:Command line:install -P dep_env

项目构建工具

插件

使用IDEA的时候,构建是IDEA帮我们构建的。

Maven构建:清理,编译,测试,报告,打包,部署。

插件有包在官网查看

clean阶段

  1. pre-clean:清理之前

  2. clean:清理

  3. post-clean:清理之后

default阶段

  1. validata:校验

  2. initialize:初始化

  3. generate-sources:生成源码

  4. process-sources:处理源码

  5. generate-resources:生成源文件

  6. process-resources:处理源文件

  7. compile:源代码【编译】

  8. process-classes:处理类文件

  9. generate-test-sources:生成测试源码

  10. process-test-sources:处理测试源码

  11. generate-test-resources:生成测试源文件

  12. process-test-resources:处理测试源文件

  13. test-compile:测试源码【编译】

  14. process-test-compile:处理测试类文件

  15. test:执行测试代码【测试】

  16. prepare-package:准备打包

  17. package:【打包】

  18. pre-integration-test:集成测试前

  19. integration-test:集成测试

  20. post-integration-test:集成测试后

  21. verify:验证

  22. install:打包上传到本地库【安装】

  23. deploy:打包上传到远程库【部署】

site阶段

  1. pre-site:生成站点文件前

  2. site:生成站点文件

  3. post-site:生成站点文件后

  4. site-deploy:生成站点文档部署到服务器【服务器】

目录结构

web目录结构

1. 原始目录【项目】
   1. src【源代码】之后会存放到WEB-INF下
   2. web【静态文件】
      1. WEB-INF【不被直接访问的资源】
         1. libs【依赖包】
         2. web.xml【配置文件】
2. 编译目录【out/artifacts/项目war包】
   1. WEB-INF
      1. classes
      2. libs
      3. web.xml

Maven目录

  1. pom.xml

  2. src(main,test)

    1. main(java,reources)

      1. webapp

        1. WEB-INF

          1. web.xml

        2. index.html

    2. test(java,resource)

跳过测试

解决场景

  1. 整体模块未开发完毕

  2. 模块某个功能为开发完毕

  3. 单个功能调试导致其他功能失败

  4. 打包加速

实现

  1. mvn install -D skipTests【跳过所有测试】

  2. 点击test横线也可以跳过

Nexus私服

SpringBoot

只需要spring-boot-starter-web一个依赖

解决问题

  1. 提供大量默认配置

  2. 内嵌web服务器

  3. 监控健康检查

启动Boot

  1. pom文件

  2. parent:spring-boot-starter-parent

  3. dependency:spring-boot-starter

  4. 主类

  5. @SpringBootApplication

  6. SpringApplication.run(主类,参数);

父依赖

  1. 最顶层父项目管理了依赖版本【主要依赖】

  2. 直接父项目管理插件版本【主要插件】

依赖配置

  1. web场景启动器:spring-boot-starter-web

  2. 打jar包插件:spring-boot-maven-plugin

启动项目

  1. java -jar springboot的jar包

启动类

main方法中SpringApplication运行返回的是IOC容器

spring-boot-autoconfigure

注解@SpringBootApplication

  1. @SpringBootConfiguration

    1. Configuration

      1. proxyBeanMethods设置true:单例【Full模式】

      2. proxyBeanMethods设置false:多例【Lite模式】

  2. @EnableAutoConfiguration【自动配置选取】

    1. @AutoConfigurationPackage

      1. @Import(AutoConfigurationPackages.Registrar.class)【将启动类所在包下的组件全部导入到容器】

    2. @Import(AutoConfigurationImportSelector.class)【筛选导入】

      1. autoconfigure的META-INF/spring-factories文件的127个场景启动器

      2. @Condition满足才生效,筛选组件

  3. @ComponentScan

组件配置

  1. @Import:引入配置类

  2. @Conditional:条件注入组件

  3. @ImportResource:导入资源【将xml加入进去】

  4. @ConfigurationProperties:组件才能使用配置绑定【核心配置】

  5. @EnableConfigurationProperties:有注入到容器和配置绑定【核心配置】

配置特性

  1. 自定义会覆盖

  2. ServletWebServerFactoryCustomizer自定义器

相关工具

lombok

实体类的相关方法。

  1.     <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
  2. lombok插件

  3. 相关注解

    1. @Slf4j

    2. @Data

      1. @Getter

      2. @Setter

      3. @ToString

      4. @EqualsAndHashCode

      5. @RequiredArgsConstructor

        1. @AllArgsConstructor:全参构造

        2. @NoArgsConstructor:无参构造

Dev-tools

热部署

  1.     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

yml配置

语法

  1. 【k: v】基本语法冒号后面有空格,不能tab缩进代替

  2. 缩进代表上下级关系

  3. 注释#

  4. 单引号转义

  5. 双引号不转义

表示

  1. 对象,map

    1. k: {k1: v1,k2: v2,k3: v3}

    2. k: 
          k1: v1
          k2: v2
          k3: v3
  2. 数组,单列集合

    1. k: {v1,v2,v3}

    2. k: 
       -v1
       -v2
       -v3

提示

  1.     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>

MVC

静态资源

WebMvcAutoConfiguration

静态资源位置

  1. 默认classpath下:

    1. /static

    2. /public

    3. /resources

    4. /META-INF/resources

  2. 因为它使用ResourceHttpHandler

  3. 修改资源位置:spring.resource.static-locations=classpath/xxx/xx

静态资源访问

  1. 默认访问:/**

  2. 修改默认路径:spring.mvc.static-path-pattern=/xxx/xx

欢迎页

自定义静态资源路径会影响欢迎页面

  1. 默认在静态资源中找到:index.html

  2. 默认找到template处理:/index

  3. 默认图标:favicon.ico资源

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值