Skip to content

Commit f2b2407

Browse files
committed
[docs updete]typo
1 parent 2d64450 commit f2b2407

File tree

3 files changed

+81
-8
lines changed

3 files changed

+81
-8
lines changed

docs/database/mysql/mysql-query-execution-plan.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ mysql> explain SELECT * FROM dept_emp WHERE emp_no IN (SELECT emp_no FROM dept_e
6969

7070
### id
7171

72-
SELECT 标识符,是查询中 SELECT 的序号,用来标识整个查询中 SELELCT 语句的顺序
72+
`SELECT` 标识符,用于标识每个 `SELECT` 语句的执行顺序
7373

7474
id 如果相同,从上往下依次执行。id 不同,id 值越大,执行优先级越高,如果行引用其他行的并集结果,则该值可以为 NULL。
7575

@@ -94,7 +94,9 @@ id 如果相同,从上往下依次执行。id 不同,id 值越大,执行
9494

9595
### type(重要)
9696

97-
查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
97+
查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:
98+
99+
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
98100

99101
常见的几种类型具体含义如下:
100102

docs/java/concurrent/java-concurrent-questions-02.md

-2
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,6 @@ CAS 经常会用到自旋操作来进行重试,也就是不成功就一直循
423423

424424
#### 只能保证一个共享变量的原子操作
425425

426-
CAS 只对单个共享变量有效,当操作涉及跨多个共享变量时 CAS 无效。但是从 JDK 1.5 开始,提供了`AtomicReference`类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行 CAS 操作.所以我们可以使用锁或者利用`AtomicReference`类把多个共享变量合并成一个共享变量来操作。
427-
428426
CAS 操作仅能对单个共享变量有效。当需要操作多个共享变量时,CAS 就显得无能为力。不过,从 JDK 1.5 开始,Java 提供了`AtomicReference`类,这使得我们能够保证引用对象之间的原子性。通过将多个变量封装在一个对象中,我们可以使用`AtomicReference`来执行 CAS 操作。
429427

430428
除了 `AtomicReference` 这种方式之外,还可以利用加锁来保证。

docs/system-design/framework/spring/spring-knowledge-and-questions-summary.md

+77-4
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,78 @@ private SmsService smsService;
279279
- 当一个接口存在多个实现类的情况下,`@Autowired``@Resource`都需要通过名称才能正确匹配到对应的 Bean。`Autowired` 可以通过 `@Qualifier` 注解来显式指定名称,`@Resource`可以通过 `name` 属性来显式指定名称。
280280
- `@Autowired` 支持在构造函数、方法、字段和参数上使用。`@Resource` 主要用于字段和方法上的注入,不支持在构造函数或参数上使用。
281281

282+
### 注入 Bean 的方式有哪些?
283+
284+
依赖注入 (Dependency Injection, DI) 的常见方式:
285+
286+
1. 构造函数注入:通过类的构造函数来注入依赖项。
287+
1. Setter 注入:通过类的 Setter 方法来注入依赖项。
288+
1. Field(字段) 注入:直接在类的字段上使用注解(如 `@Autowired``@Resource`)来注入依赖项。
289+
290+
构造函数注入示例:
291+
292+
```java
293+
@Service
294+
public class UserService {
295+
296+
private final UserRepository userRepository;
297+
298+
public UserService(UserRepository userRepository) {
299+
this.userRepository = userRepository;
300+
}
301+
302+
//...
303+
}
304+
```
305+
306+
Setter 注入示例:
307+
308+
```java
309+
@Service
310+
public class UserService {
311+
312+
private UserRepository userRepository;
313+
314+
// 在 Spring 4.3 及以后的版本,特定情况下 @Autowired 可以省略不写
315+
@Autowired
316+
public void setUserRepository(UserRepository userRepository) {
317+
this.userRepository = userRepository;
318+
}
319+
320+
//...
321+
}
322+
```
323+
324+
Field 注入示例:
325+
326+
```java
327+
@Service
328+
public class UserService {
329+
330+
@Autowired
331+
private UserRepository userRepository;
332+
333+
//...
334+
}
335+
```
336+
337+
### 构造函数注入还是 Setter 注入?
338+
339+
Spring 官方有对这个问题的回答:<https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html#beans-setter-injection>
340+
341+
我这里主要提取总结完善一下 Spring 官方的建议。
342+
343+
**Spring 官方推荐构造函数注入**,这种注入方式的优势如下:
344+
345+
1. 依赖完整性:确保所有必需依赖在对象创建时就被注入,避免了空指针异常的风险。
346+
2. 不可变性:有助于创建不可变对象,提高了线程安全性。
347+
3. 初始化保证:组件在使用前已完全初始化,减少了潜在的错误。
348+
4. 测试便利性:在单元测试中,可以直接通过构造函数传入模拟的依赖项,而不必依赖 Spring 容器进行注入。
349+
350+
构造函数注入适合处理**必需的依赖项**,而 **Setter 注入** 则更适合**可选的依赖项**,这些依赖项可以有默认值或在对象生命周期中动态设置。虽然 `@Autowired` 可以用于 Setter 方法来处理必需的依赖项,但构造函数注入仍然是更好的选择。
351+
352+
在某些情况下(例如第三方类不提供 Setter 方法),构造函数注入可能是**唯一的选择**
353+
282354
### Bean 的作用域有哪些?
283355

284356
Spring 中 Bean 的作用域通常有下面几种:
@@ -802,7 +874,7 @@ class B {
802874

803875
`@Lazy` 用来标识类是否需要懒加载/延迟加载,可以作用在类上、方法上、构造器上、方法参数上、成员变量中。
804876

805-
Spring Boot 2.2 新增了全局懒加载属性,开启后全局 bean 被设置为懒加载,需要时再去创建。
877+
Spring Boot 2.2 新增了**全局懒加载属性**,开启后全局 bean 被设置为懒加载,需要时再去创建。
806878

807879
配置文件配置全局懒加载:
808880

@@ -829,11 +901,12 @@ springApplication.run(args);
829901
- 由于在 A 上标注了 `@Lazy` 注解,因此 Spring 会去创建一个 B 的代理对象,将这个代理对象注入到 A 中的 B 属性;
830902
- 之后开始执行 B 的实例化、初始化,在注入 B 中的 A 属性时,此时 A 已经创建完毕了,就可以将 A 给注入进去。
831903

832-
通过 `@Lazy` 就解决了循环依赖的注入, 关键点就在于对 A 中的属性 B 进行注入时,注入的是 B 的代理对象,因此不会循环依赖
904+
从上面的加载流程可以看出: `@Lazy` 解决循环依赖的关键点在于代理对象的使用
833905

834-
之前说的发生循环依赖是因为在对 A 中的属性 B 进行注入时,注入的是 B 对象,此时又会去初始化 B 对象,发现 B 又依赖了 A,因此才导致的循环依赖。
906+
- **没有 `@Lazy` 的情况下**:在 Spring 容器初始化 `A` 时会立即尝试创建 `B`,而在创建 `B` 的过程中又会尝试创建 `A`,最终导致循环依赖(即无限递归,最终抛出异常)。
907+
- **使用 `@Lazy` 的情况下**Spring 不会立即创建 `B`,而是会注入一个 `B` 的代理对象。由于此时 `B` 仍未被真正初始化,`A` 的初始化可以顺利完成。等到 `A` 实例实际调用 `B` 的方法时,代理对象才会触发 `B` 的真正初始化。
835908

836-
一般是不建议使用循环依赖的,但是如果项目比较复杂,可以使用 `@Lazy` 解决一部分循环依赖的问题
909+
`@Lazy` 能够在一定程度上打破循环依赖链,允许 Spring 容器顺利地完成 Bean 的创建和注入。但这并不是一个根本性的解决方案,尤其是在构造函数注入、复杂的多级依赖等场景中,`@Lazy` 无法有效地解决问题。因此,最佳实践仍然是尽量避免设计上的循环依赖
837910

838911
### SpringBoot 允许循环依赖发生么?
839912

0 commit comments

Comments
 (0)