Web基础

分层解耦

三层架构

  • Controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
  • Service:业务逻辑层,处理具体的业务逻辑。
  • Dao:数据访问层(Data Access 0bject)(持久层),负责数据访问操作,包括数据的增、删、改、查。
    三层架构
    处理请求时,Controller进行接收并调用Service,Service调用Dao进行数据访问并进行业务处理,然后将结果返回给Controller,Controller再对前端进行响应。

分层解耦

  • 耦合:衡量软件中各个层/各个模块的依赖关联程度。
  • 内聚:软件中各个功能模块内部的功能联系。
  • 软件设计原则:高内聚低耦合。

IOC&DI

  • 控制反转:Inversion Of Control, IOC。对象的创建控制权由程序自身转移到外部(容器)。
  • 依赖注入:Dependency Injection, DI。容器为应用程序提供运行时所依赖的资源。
  • Bean对象:IOC容器中创建、管理的对象。
    实现分层解耦:将项目中的类交给IOC容器管理,应用程序需要什么对象直接依赖容器为其提供。

@Component 将当前类交给IOC容器管理
@Autowired 应用程序运行时自动查询该类型的bean对象,并赋值给该成员变量

IOC
注解 位置 说明
@Component 不属于以下三类时用此注解 声明bean的基础注解
@Controller 标注在控制层类上 @Component的衍生注解
@Service 标注在业务层类上 @Component的衍生注解
@Repository 标注在数据访问层类上 @Component的衍生注解
DI
  • 属性注入
    1
    2
    3
    4
    5
    @RestController
    public class UserController {
    @Autowired
    private UserService userService;
    }
    • 优点:代码简洁,方便快速开发
    • 缺点:隐藏了类之间的依赖关系,可能会破坏类的封装性。
  • 构造函数注入
    1
    2
    3
    4
    5
    6
    7
    8
    @RestController
    public class UserController {
    private final UserService userService;
    @Autowired
    public UserController(UserService userService) {
    this.userService = userService;
    }
    }
    • 优点:能清晰地看到类的依赖关系,提高了代码的安全性。
    • 缺点:代码繁琐,如果构造参数过多,可能会导致构造函数臃肿。
  • setter注入
    1
    2
    3
    4
    5
    6
    7
    8
    @RestController
    public class UserController {
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
    this.userService = userService;
    }
    }

MyBatis

数据库连接池

数据库连接池是个容器,负责分配、管理数据库连接。
它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。
释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏。

增删改查

#{…} 占位符。执行时替换为?,生成预编译SQL
${…} 拼接符。直接将参数拼接在SQL语句中,存在SQL注入问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Select("select id, username, password, name, age from user")
public List<User> findAll();

@Select("select * from user where username = #{username} and password = #{password}")
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
// 基于官方骨架创建的springboot项目中,接口编译时会保留方法形参名,@Param注解可以省略

@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);

@Insert("insert into user(username, password, name, age) values (#{username}, #{password}, #{name}, #{age})")
public void insert(User user);

@Update("update user set username = #{username}, age = #{age} where id = #{id}")
public void update(User user);

苍穹外卖

JWT认证机制

JSON Web Token(JSON Web令牌)

传统Session

http协议本身是一种无状态的协议,如果用户向服务器提供了用户名和密码来进行用户认证,下次请求时,用户还要再一次进行用户认证才行。因为根据http协议,服务器并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储─份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样应用就能识别请求来自哪个用户。

JWT认证

JWT

  1. 前端通过Web表单将自己的用户名和密码发送到后端的接口。该过程一般是HTTP的POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
  2. 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT(Token)。
  3. 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage(浏览器本地缓存)或sessionStorage(session缓存)上,退出登录时前端删除保存的JWT即可。
  4. 前端在每次请求时将JWT放入HTTP的Header中的Authorization位。(解决XSS和XSRF问题)
    后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确﹔检查Token是否过期;检查Token的接收方是否是自己
  5. 验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

Nginx

Nginx反向代理的好处:

  • 提供缓存提高访问速度
  • 进行负载均衡,把大量请求分配给集群中的服务器
  • 保证后端服务安全,前端无法直接请求到后端服务,要通过Ngnix转发

负载均衡策略

名称 说明
轮询 默认方式
weight 权重方式,默认为1,权重越高,被分配的客户端请求就越多
ip_hash 依据ip分配方式,每个访客可以固定访问一个后端服务
least_conn 依据最少连接方式,把请求优先分配给连接数少的后端服务
url_hash 依据url分配方式,相同的url会被分配到同一个后端服务
fari 依据响应时间方式,响应时间短的服务将会被优先分配

ThreadLocal

每个请求中的操作同属一个线程。
ThreadLocal为每个线程提供一份单独的存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

1
2
3
public void set(T value);    // 设置当前线程的线程局部变量的值
public T get(); // 返回当前线程所对应的线程局部变量的值
public void remove(); // 移除当前线程的线程局部变量

AOP

Aspect Orient Programming,面向切面编程
在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。
采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。
主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
AOP

名称 说明
Joinpoint(连接点) 可以被动态代理拦截目标类的方法
Pointcut(切入点) 被拦截的连接点
Advice(通知) 对切入点增强的内容
Target(目标) 代理的目标对象
Weaving(植入) 把增强代码应用到目标上,生成代理对象的过程
Proxy(代理) 生成的代理对象
Aspect(切面) 切入点和通知的结合

Redis

Redis是一个基于内存的 key-value 结构数据库。

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品、资讯、新闻)

常用数据类型

  • 字符串 string
  • 哈希 hash
  • 列表 list
  • 集合 set
  • 有序集合 sorted set / zset

常用命令

字符串
SET key value 设置指定 key 的值
GET key 获取指定 key 的值
SETEX key seconds value 设置指定 key 的值,并将 key 的过期时间设为 seconds 秒
SETNX key value 只有在 key 不存在时设置 key 的值
哈希

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。

HSET key field value 将哈希表 key 中的字段 field 的值设为 value
HGET key field 获取存储在哈希表中指定字段的值
HDEL key field 删除存储在哈希表中的指定字段
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值
列表

Redis 列表是简单的字符串列表,按照插入顺序排序。

LPUSH key valuel [value2] 将一个或多个值插入到列表头部
LRANGE key start stop 获取列表指定范围内的元素
RPOP key 移除并获取列表最后一个元素
LLEN key 获取列表长度
集合

Redis set 是 string 类型的无序集合。集合成员是唯一的,集合中不能出现重复的数据。

SADD key member1 [member2] 向集合添加一个或多个成员
SMEMBERS key 返回集合中的所有成员
SCARD key 获取集合的成员数
SINTER key1 [key2] 返回给定所有集合的交集
SUNION key1 [key2] 返回所有给定集合的并集
SREM key memberl [member2] 删除集合中一个或多个成员
有序集合

Redis 有序集合是 string 类型元素的集合,且不允许有重复成员。每个元素都会关联一个 double 类型的分数。

ZADD key scorel memberl [score2 member2] 向有序集合添加一个或多个成员
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment
ZREM key member [member…] 移除有序集合中的一个或多个成员
通用命令
KEYS pattern 查找所有符合给定模式(pattern)的 key
EXISTS key 检查给定 key 是否存在
TYPE key 返回 key 所储存的值的类型
DEL key 在 key 存在时删除 key

Spring Cache

Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache 提供了一层抽象,底层可以切换不同的缓存实现,例如:

  • EHCache
  • Caffeine
  • Redis

常用注解

注解 说明
@EnableCaching 开启缓存注解功能,通常加在启动类上
@Cacheable 在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中
@CachePut 将方法的返回值放到缓存中
@CacheEvict 将一条或多条数据从缓存中删除

微信支付



cron表达式

提供cron表达式可以定义任务触发的时间
构成规则:分为 6 或 7 个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:秒、分钟、小时、日、月、周、年(可选)

WebSocket

WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

HTTP VS WebSocket

  • HTTP 是短连接;WebSocket 是长连接
  • HTTP 通信是单向的,基于请求响应模式;WebSocket 支持双向通信
  • HTTP 和 WebSocket 底层都是 TCP 连接

应用场景

  • 视频弹幕
  • 网页聊天
  • 体育实况更新
  • 股票基金报价实时更新