mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
[docs update]IoC和AOP详解完善
This commit is contained in:
parent
c3b6743ef5
commit
9b3a71c2cb
@ -45,22 +45,22 @@ export default hopeTheme({
|
|||||||
components: {
|
components: {
|
||||||
rootComponents: {
|
rootComponents: {
|
||||||
// https://plugin-components.vuejs.press/zh/guide/utilities/notice.html#%E7%94%A8%E6%B3%95
|
// https://plugin-components.vuejs.press/zh/guide/utilities/notice.html#%E7%94%A8%E6%B3%95
|
||||||
notice: [
|
// notice: [
|
||||||
{
|
// {
|
||||||
path: "/",
|
// path: "/",
|
||||||
title: "PDF面试资料(2024版)",
|
// title: "PDF面试资料(2024版)",
|
||||||
showOnce: true,
|
// showOnce: true,
|
||||||
content:
|
// content:
|
||||||
"2024最新版原创PDF面试资料来啦!涵盖 Java 核心、数据库、缓存、分布式、设计模式、智力题等内容,非常全面!",
|
// "2024最新版原创PDF面试资料来啦!涵盖 Java 核心、数据库、缓存、分布式、设计模式、智力题等内容,非常全面!",
|
||||||
actions: [
|
// actions: [
|
||||||
{
|
// {
|
||||||
text: "点击领取",
|
// text: "点击领取",
|
||||||
link: "https://oss.javaguide.cn/backend-notekbook/official-account-traffic-backend-notebook-with-data-screenshot.png",
|
// link: "https://oss.javaguide.cn/backend-notekbook/official-account-traffic-backend-notebook-with-data-screenshot.png",
|
||||||
type: "primary",
|
// type: "primary",
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -184,7 +184,9 @@ The content read from file:§å®¶å¥½
|
|||||||
|
|
||||||
因此,I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。
|
因此,I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。
|
||||||
|
|
||||||
字符流默认采用的是 `Unicode` 编码,我们可以通过构造方法自定义编码。顺便分享一下之前遇到的笔试题:常用字符编码所占字节数?`utf8` :英文占 1 字节,中文占 3 字节,`unicode`:任何字符都占 2 个字节,`gbk`:英文占 1 字节,中文占 2 字节。
|
字符流默认采用的是 `Unicode` 编码,我们可以通过构造方法自定义编码。
|
||||||
|
|
||||||
|
Unicode 本身只是一种字符集,它为每个字符分配一个唯一的数字编号,并没有规定具体的存储方式。UTF-8、UTF-16、UTF-32 都是 Unicode 的编码方式,它们使用不同的字节数来表示 Unicode 字符。例如,UTF-8 :英文占 1 字节,中文占 3 字节。
|
||||||
|
|
||||||
### Reader(字符输入流)
|
### Reader(字符输入流)
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ icon: "xitongsheji"
|
|||||||
- [MyBatis-Plus](https://github.com/baomidou/mybatis-plus) : [MyBatis](http://www.mybatis.org/mybatis-3/) 增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
|
- [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、分页查询、多表查询、批量操作。
|
- [MyBatis-Flex](https://gitee.com/mybatis-flex/mybatis-flex):一个优雅的 MyBatis 增强框架,无其他任何第三方依赖,支持 CRUD、分页查询、多表查询、批量操作。
|
||||||
- [jOOQ](https://github.com/jOOQ/jOOQ):用 Java 编写 SQL 的最佳方式。
|
- [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项目介绍")。
|
||||||
|
|
||||||
### 数据同步
|
### 数据同步
|
||||||
|
|
||||||
@ -152,6 +152,11 @@ icon: "xitongsheji"
|
|||||||
|
|
||||||
相关阅读:[Skywalking 官网对于主流开源链路追踪系统的对比](https://skywalking.apache.org/zh/blog/2019-03-29-introduction-of-skywalking-and-simple-practice.html)
|
相关阅读:[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 锁实现。
|
||||||
|
|
||||||
## 高性能
|
## 高性能
|
||||||
|
|
||||||
### 多线程
|
### 多线程
|
||||||
|
@ -36,7 +36,7 @@ IoC (Inversion of Control )即控制反转/反转控制。它是一种思想
|
|||||||
- **控制** :指的是对象创建(实例化、管理)的权力
|
- **控制** :指的是对象创建(实例化、管理)的权力
|
||||||
- **反转** :控制权交给外部环境(IoC 容器)
|
- **反转** :控制权交给外部环境(IoC 容器)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### IoC 解决了什么问题?
|
### IoC 解决了什么问题?
|
||||||
|
|
||||||
@ -49,17 +49,15 @@ IoC 的思想就是两方之间不互相依赖,由第三方容器来管理相
|
|||||||
|
|
||||||
在没有使用 IoC 思想的情况下,Service 层想要使用 Dao 层的具体实现的话,需要通过 new 关键字在`UserServiceImpl` 中手动 new 出 `IUserDao` 的具体实现类 `UserDaoImpl`(不能直接 new 接口类)。
|
在没有使用 IoC 思想的情况下,Service 层想要使用 Dao 层的具体实现的话,需要通过 new 关键字在`UserServiceImpl` 中手动 new 出 `IUserDao` 的具体实现类 `UserDaoImpl`(不能直接 new 接口类)。
|
||||||
|
|
||||||

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

|

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

|

|
||||||
|
|
||||||
### IoC 和 DI 有区别吗?
|
### IoC 和 DI 有区别吗?
|
||||||
|
|
||||||
@ -87,6 +85,8 @@ AOP 的目的是将横切关注点(如日志记录、事务管理、权限控
|
|||||||
|
|
||||||
AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切关注点从核心业务逻辑中分离出来,形成一个个的**切面(Aspect)**。
|
AOP 之所以叫面向切面编程,是因为它的核心思想就是将横切关注点从核心业务逻辑中分离出来,形成一个个的**切面(Aspect)**。
|
||||||
|
|
||||||
|

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

|
||||||
|
|
||||||
|
- **Before**(前置通知):目标对象的方法调用之前触发
|
||||||
|
- **After** (后置通知):目标对象的方法调用之后触发
|
||||||
|
- **AfterReturning**(返回通知):目标对象的方法调用完成,在返回结果值之后触发
|
||||||
|
- **AfterThrowing**(异常通知):目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。
|
||||||
|
- **Around** (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法
|
||||||
|
|
||||||
### AOP 解决了什么问题?
|
### AOP 解决了什么问题?
|
||||||
|
|
||||||
OOP 不能很好地处理一些分散在多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等),这些行为通常被称为 **横切关注点(cross-cutting concerns)** 。如果我们在每个类或对象中都重复实现这些行为,那么会导致代码的冗余、复杂和难以维护。
|
OOP 不能很好地处理一些分散在多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等),这些行为通常被称为 **横切关注点(cross-cutting concerns)** 。如果我们在每个类或对象中都重复实现这些行为,那么会导致代码的冗余、复杂和难以维护。
|
||||||
|
@ -358,7 +358,11 @@ class WebSite {
|
|||||||
|
|
||||||
**数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。**
|
**数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 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)的参考实现。
|
校验的时候我们实际用的是 **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)的参考实现。
|
||||||
|
|
||||||
|
@ -590,7 +590,9 @@ Spring AOP 已经集成了 AspectJ ,AspectJ 应该算的上是 Java 生态系
|
|||||||
|
|
||||||
如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。
|
如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择 AspectJ ,它比 Spring AOP 快很多。
|
||||||
|
|
||||||
### AspectJ 定义的通知类型有哪些?
|
### AOP 常见的通知类型有哪些?
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
- **Before**(前置通知):目标对象的方法调用之前触发
|
- **Before**(前置通知):目标对象的方法调用之前触发
|
||||||
- **After** (后置通知):目标对象的方法调用之后触发
|
- **After** (后置通知):目标对象的方法调用之后触发
|
||||||
|
Loading…
x
Reference in New Issue
Block a user