Skip to content

Commit

Permalink
[docs update]IoC和AOP详解完善
Browse files Browse the repository at this point in the history
  • Loading branch information
Snailclimb committed Sep 4, 2024
1 parent c3b6743 commit 9b3a71c
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 25 deletions.
32 changes: 16 additions & 16 deletions docs/.vuepress/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,22 @@ export default hopeTheme({
components: {
rootComponents: {
// https://plugin-components.vuejs.press/zh/guide/utilities/notice.html#%E7%94%A8%E6%B3%95
notice: [
{
path: "/",
title: "PDF面试资料(2024版)",
showOnce: true,
content:
"2024最新版原创PDF面试资料来啦!涵盖 Java 核心、数据库、缓存、分布式、设计模式、智力题等内容,非常全面!",
actions: [
{
text: "点击领取",
link: "https://oss.javaguide.cn/backend-notekbook/official-account-traffic-backend-notebook-with-data-screenshot.png",
type: "primary",
},
],
},
],
// notice: [
// {
// path: "/",
// title: "PDF面试资料(2024版)",
// showOnce: true,
// content:
// "2024最新版原创PDF面试资料来啦!涵盖 Java 核心、数据库、缓存、分布式、设计模式、智力题等内容,非常全面!",
// actions: [
// {
// text: "点击领取",
// link: "https://oss.javaguide.cn/backend-notekbook/official-account-traffic-backend-notebook-with-data-screenshot.png",
// type: "primary",
// },
// ],
// },
// ],
},
},

Expand Down
4 changes: 3 additions & 1 deletion docs/java/io/io-basis.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ The content read from file:§å®¶å¥½

因此,I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。

字符流默认采用的是 `Unicode` 编码,我们可以通过构造方法自定义编码。顺便分享一下之前遇到的笔试题:常用字符编码所占字节数?`utf8` :英文占 1 字节,中文占 3 字节,`unicode`:任何字符都占 2 个字节,`gbk`:英文占 1 字节,中文占 2 字节。
字符流默认采用的是 `Unicode` 编码,我们可以通过构造方法自定义编码。

Unicode 本身只是一种字符集,它为每个字符分配一个唯一的数字编号,并没有规定具体的存储方式。UTF-8UTF-16UTF-32 都是 Unicode 的编码方式,它们使用不同的字节数来表示 Unicode 字符。例如,UTF-8 :英文占 1 字节,中文占 3 字节。

### Reader(字符输入流)

Expand Down
7 changes: 6 additions & 1 deletion docs/open-source-project/system-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ icon: "xitongsheji"
- [MyBatis-Plus](https://github.com/baomidou/mybatis-plus) : [MyBatis](http://www.mybatis.org/mybatis-3/) 增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
- [MyBatis-Flex](https://gitee.com/mybatis-flex/mybatis-flex):一个优雅的 MyBatis 增强框架,无其他任何第三方依赖,支持 CRUD、分页查询、多表查询、批量操作。
- [jOOQ](https://github.com/jOOQ/jOOQ):用 Java 编写 SQL 的最佳方式。
- [Redisson](https://github.com/redisson/redisson "redisson"):Redis 基础上的一个 Java 驻内存数据网格In-Memory Data Grid),支持超过 30 个对象和服务:`Set`,`SortedSet`, `Map`, `List`, `Queue`, `Deque` ……,并且提供了多种分布式锁的实现。更多介绍请看:[Redisson 项目介绍](https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D "Redisson项目介绍")
- [Redisson](https://github.com/redisson/redisson "redisson")Redisson 是一款架设在 Redis 基础之上的 Java 驻内存数据网格 (In-Memory Data Grid),它充分利用了 Redis 键值数据库的优势,为 Java 开发者提供了一系列具有分布式特性的常用工具类。例如,分布式 Java 对象(`Set``SortedSet``Map``List``Queue``Deque` 等)、分布式锁等。详细介绍请看:[Redisson 项目介绍](https://github.com/redisson/redisson/wiki/Redisson%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D "Redisson项目介绍")

### 数据同步

Expand Down Expand Up @@ -152,6 +152,11 @@ icon: "xitongsheji"

相关阅读:[Skywalking 官网对于主流开源链路追踪系统的对比](https://skywalking.apache.org/zh/blog/2019-03-29-introduction-of-skywalking-and-simple-practice.html)

### 分布式锁

- [Lock4j](https://gitee.com/baomidou/lock4j):支持 Redisson、ZooKeeper 等不同方案的高性能分布式锁。
- [Redisson](https://github.com/redisson/redisson "redisson"):Redisson 在分布式锁方面提供全面且强大的支持,超越了简单的 Redis 锁实现。

## 高性能

### 多线程
Expand Down
20 changes: 15 additions & 5 deletions docs/system-design/framework/spring/ioc-and-aop.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ IoC (Inversion of Control )即控制反转/反转控制。它是一种思想
- **控制** :指的是对象创建(实例化、管理)的权力
- **反转** :控制权交给外部环境(IoC 容器)

![IoC 图解](https://oss.javaguide.cn/java-guide-blog/frc-365faceb5697f04f31399937c059c162.png)
![IoC 图解](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration.png)

### IoC 解决了什么问题?

Expand All @@ -49,17 +49,15 @@ IoC 的思想就是两方之间不互相依赖,由第三方容器来管理相

在没有使用 IoC 思想的情况下,Service 层想要使用 Dao 层的具体实现的话,需要通过 new 关键字在`UserServiceImpl` 中手动 new 出 `IUserDao` 的具体实现类 `UserDaoImpl`(不能直接 new 接口类)。

![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/ioc-kfji3.png)

很完美,这种方式也是可以实现的,但是我们想象一下如下场景:

开发过程中突然接到一个新的需求,针对`IUserDao` 接口开发出另一个具体实现类。因为 Server 层依赖了`IUserDao`的具体实现,所以我们需要修改`UserServiceImpl`中 new 的对象。如果只有一个类引用了`IUserDao`的具体实现,可能觉得还好,修改起来也不是很费力气,但是如果有许许多多的地方都引用了`IUserDao`的具体实现的话,一旦需要更换`IUserDao` 的实现方式,那修改起来将会非常的头疼。

![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/why-ioc.png)
![IoC&Aop-ioc-illustration-dao-service](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration-dao-service.png)

使用 IoC 的思想,我们将对象的控制权(创建、管理)交由 IoC 容器去管理,我们在使用的时候直接向 IoC 容器 “要” 就可以了

![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/why-ioc-2.png)
![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/IoC&Aop-ioc-illustration-dao.png)

### IoC 和 DI 有区别吗?

Expand Down Expand Up @@ -87,6 +85,8 @@ AOP 的目的是将横切关注点(如日志记录、事务管理、权限控

AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切关注点从核心业务逻辑中分离出来,形成一个个的**切面(Aspect)**

![面向切面编程图解](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/aop-program-execution.jpg)

这里顺带总结一下 AOP 关键术语(不理解也没关系,可以继续往下看):

- **横切关注点(cross-cutting concerns)** :多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等)。
Expand All @@ -96,6 +96,16 @@ AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切
- **切点(Pointcut)**:一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 `execution(* com.xyz.service..*(..))`匹配 `com.xyz.service` 包及其子包下的类或接口。
- **织入(Weaving)**:织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。常见的织入时机有两种,分别是编译期织入(Compile-Time Weaving 如:AspectJ)和运行期织入(Runtime Weaving 如:AspectJ、Spring AOP)。

### AOP 常见的通知类型有哪些?

![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/aspectj-advice-types.jpg)

- **Before**(前置通知):目标对象的方法调用之前触发
- **After** (后置通知):目标对象的方法调用之后触发
- **AfterReturning**(返回通知):目标对象的方法调用完成,在返回结果值之后触发
- **AfterThrowing**(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。
- **Around** (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法

### AOP 解决了什么问题?

OOP 不能很好地处理一些分散在多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等),这些行为通常被称为 **横切关注点(cross-cutting concerns)** 。如果我们在每个类或对象中都重复实现这些行为,那么会导致代码的冗余、复杂和难以维护。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,11 @@ class WebSite {

**数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。**

**JSR(Java Specification Requests)** 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,这样就可以在需要校验的时候进行校验了,非常方便!
Bean Validation 是一套定义 JavaBean 参数校验标准的规范 (JSR 303, 349, 380),它提供了一系列注解,可以直接用于 JavaBean 的属性上,从而实现便捷的参数校验。

- **JSR 303 (Bean Validation 1.0):** 奠定了基础,引入了核心校验注解(如 `@NotNull`、`@Size`、`@Min`、`@Max` 等),定义了如何通过注解的方式对 JavaBean 的属性进行校验,并支持嵌套对象校验和自定义校验器。
- **JSR 349 (Bean Validation 1.1):** 在 1.0 基础上进行扩展,例如引入了对方法参数和返回值校验的支持、增强了对分组校验(Group Validation)的处理。
- **JSR 380 (Bean Validation 2.0):** 拥抱 Java 8 的新特性,并进行了一些改进,例如支持 `java.time` 包中的日期和时间类型、引入了一些新的校验注解(如 `@NotEmpty`, `@NotBlank`等)。

校验的时候我们实际用的是 **Hibernate Validator** 框架。Hibernate Validator 是 Hibernate 团队最初的数据校验框架,Hibernate Validator 4.x 是 Bean Validation 1.0(JSR 303)的参考实现,Hibernate Validator 5.x 是 Bean Validation 1.1(JSR 349)的参考实现,目前最新版的 Hibernate Validator 6.x 是 Bean Validation 2.0(JSR 380)的参考实现。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,9 @@ Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系

如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。

### AspectJ 定义的通知类型有哪些?
### AOP 常见的通知类型有哪些?

![](https://oss.javaguide.cn/github/javaguide/system-design/framework/spring/aspectj-advice-types.jpg)

- **Before**(前置通知):目标对象的方法调用之前触发
- **After** (后置通知):目标对象的方法调用之后触发
Expand Down

0 comments on commit 9b3a71c

Please sign in to comment.