Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 63c60ad

Browse files
"文档初始化"
1 parent 7d8e0f3 commit 63c60ad

14 files changed

+749
-278
lines changed

‎Spring/2 Spring是如何实现事件监听机制的? Spring源码(二).md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,9 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
502502

503503
小结:这篇文章是本人第二篇源码解析的文章,写作速度仍然很慢,希望以后思路捋清楚后能快点写完,加油。
504504

505+
/Users/zhangyuhang/Library/Application Support/JetBrains/IntelliJIdea2020.1/plugins
505506

507+
/Users/zhangyuhang/Library/Application Support/JetBrains/IntelliJIdea2020.1/port
506508

507509
参考:
508510

‎Spring/Spring常用注解(三).md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# 1 Spring常用注解
2+
3+
4+
5+
# 2 Spring 注解注册bean
6+
7+
## 2.1 @Configuration
8+
9+
```java
10+
@Import(ConditionConfig.class)//参见https://www.cnblogs.com/iiiiiher/p/12781618.html
11+
@Configuration //该注解相当于xml
12+
public class BasicConfig {
13+
@Bean//默认不指定名字,则bean id是返回值类型名字,该注解相当于xml中<bean id="student" name="getSut1" type="com.ymbj.config.Student"></bean>
14+
//@Primary
15+
public Student getStu1() {
16+
return new Student("小张", 12);
17+
}
18+
19+
@Bean
20+
public Student getStu2() {
21+
return new Student("小李", 20);
22+
}
23+
}
24+
25+
// id name https://www.cnblogs.com/xiewuqing/p/4678407.html
26+
// bean name https://www.cnblogs.com/1540340840qls/p/6962777.html
27+
// Spring创建bean默认的id值 https://www.jianshu.com/p/77d0ec46703c
28+
//spring中bean配置和bean注入 https://www.cnblogs.com/wuchanming/p/5426746.html
29+
```
30+
31+
32+
33+
34+
35+
## 2.2 @Bean
36+
37+
注意,形参默认使用@Autowire
38+
39+
xml name type
40+
41+
## 2.3 @Import
42+
43+
## 2.4 @Primary
44+
45+
## 2.5 @Component
46+
47+
### 2.5.1 @Controller@RestfulController
48+
49+
### 2.5.2 @Service
50+
51+
### 2.5.3 @Repository
52+
53+
# 3 Spring 使用注解注入
54+
55+
## 3.1 @Autoware@Qualifier
56+
57+
默认是通过类型(byType)找bean,如存在多个类型则通过名称(byName)找bean
58+
59+
```java
60+
61+
```
62+
63+
三种解决方案
64+
65+
1、注册bean 使用@Primary
66+
67+
2、注册bean时指定注入时属性名称为bean name,覆盖name=默认方法名;这种不合适声明(注册)bean和使用(注入)耦合过密bean
68+
69+
3、注入时,使用@Qualifier注解显式指定bean name(推荐)
70+
71+
## 3.2 @Resource ?
72+
73+
首先`@Resource`不是Spring的注解,是JavaEE的注解,默认是先按照名称(byName)找bean,如名称无找到则通过类型(byType)
74+
75+
https://blog.csdn.net/weixin_40423597/article/details/80643990
76+
77+
https://www.yuque.com/docs/share/fe2e6770-216c-4ea8-a56c-3c94b90faf46

‎SpringBoot/1 如何搭建自己的SpringBoot源码调试环境? SpringBoot源码(一).md

Lines changed: 244 additions & 19 deletions
Large diffs are not rendered by default.

‎SpringBoot/6 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六).md renamed to ‎SpringBoot/10 SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(十).md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11

22
# 1 温故而知新
3-
本篇接 [外部配置属性值是如何被绑定到XxxProperties类属性上的?--SpringBoot源码(五)](https://github.com/yuanmabiji/Java-SourceCode-Blogs/blob/master/SpringBoot/5%20SpringBoot%E7%9A%84%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%80%BC%E6%98%AF%E5%A6%82%E4%BD%95%E7%BB%91%E5%AE%9A%E7%9A%84%EF%BC%9F%20SpringBoot%E6%BA%90%E7%A0%81%EF%BC%88%E4%BA%94%EF%BC%89.md)
4-
53
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot**外部配置属性值是如何被绑定到XxxProperties类属性上**的相关源码,现将外部属性绑定的重要步骤总结如下:
64
1. 首先是`@EnableConfigurationProperties`注解`import``EnableConfigurationPropertiesImportSelector`后置处理器;
75
2. `EnableConfigurationPropertiesImportSelector`后置处理器又向`Spring`容器中注册了`ConfigurationPropertiesBeanRegistrar``ConfigurationPropertiesBindingPostProcessorRegistrar`这两个`bean`;
@@ -199,7 +197,6 @@ Maven的`optional`标签表示可选依赖即不可传递的意思,下面直
199197

200198
注:该源码分析对应SpringBoot版本为**2.1.0.RELEASE**,本文对应的SpringBoot源码解析项目github地址:https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE
201199

202-
203200
参考:
204-
1,[Maven 依赖传递性透彻理解](https://dayarch.top/p/maven-dependency-optional-transitive.html)
205201

202+
1. [Maven 依赖传递性透彻理解](https://dayarch.top/p/maven-dependency-optional-transitive.html)

‎SpringBoot/7 SpringBoot的启动流程是怎样的?SpringBoot源码(七).md renamed to ‎SpringBoot/3 SpringBoot的启动流程是怎样的?SpringBoot源码(三).md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11

22
# 1 温故而知新
3-
本篇接 [SpringBoot内置的各种Starter是怎样构建的? SpringBoot源码(六)](https://github.com/yuanmabiji/Java-SourceCode-Blogs/blob/master/SpringBoot/6%20SpringBoot%E5%86%85%E7%BD%AE%E7%9A%84%E5%90%84%E7%A7%8DStarter%E6%98%AF%E6%80%8E%E6%A0%B7%E6%9E%84%E5%BB%BA%E7%9A%84%EF%BC%9F%20%20SpringBoot%E6%BA%90%E7%A0%81%EF%BC%88%E5%85%AD%EF%BC%89.md)
3+
本篇接
4+
[如何分析SpringBoot源码模块及结构?--SpringBoot源码(二)](https://github.com/yuanmabiji/Java-SourceCode-Blogs/blob/master/SpringBoot/2%20%E5%A6%82%E4%BD%95%E5%88%86%E6%9E%90SpringBoot%E6%BA%90%E7%A0%81%E6%A8%A1%E5%9D%97%E5%8F%8A%E7%BB%93%E6%9E%84%EF%BC%9F%20%20SpringBoot%E6%BA%90%E7%A0%81%EF%BC%88%E4%BA%8C%EF%BC%89.md)
45

5-
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了**SpringBoot内置的各种Starter是怎样构建的?**,现将关键点重新回顾总结下:
66

7-
1. `spring-boot-starter-xxx`起步依赖没有一行代码,而是直接或间接依赖了`xxx-autoconfigure`模块,而`xxx-autoconfigure`模块承担了`spring-boot-starter-xxx`起步依赖自动配置的实现;
8-
2. `xxx-autoconfigure`自动配置模块引入了一些可选依赖,这些可选依赖不会被传递到`spring-boot-starter-xxx`起步依赖中,这是起步依赖构建的**关键点**;
9-
3. `spring-boot-starter-xxx`起步依赖**显式**引入了一些对自动配置起作用的可选依赖,因此会触发 `xxx-autoconfigure`自动配置的逻辑(比如创建某些符合条件的配置`bean`);
10-
4. 经过前面3步的准备,我们项目只要引入了某个起步依赖后,就可以开箱即用了,而不用手动去创建一些`bean`等。
7+
上一篇分析了SpringBoot源码结构及各个模块pom之间的关系后,那么此篇开始就开始解开SpringBoot新特性之一--自动配置的神秘面纱了。因为SpringBoot自动配置原理是基于其大量的条件注解`ConditionalOnXXX`,因此,本节我们先来撸下Spring的条件注解的相关源码。
118

129
# 2 引言
13-
本来这篇文章会继续SpringBoot自动配置的源码分析的,想分析下`spring-boot-starter-web`的自动配置的源码是怎样的的。但是考虑到`spring-boot-starter-web`的自动配置逻辑跟内置`Tomcat`等有关,因此想以后等分析了SpringBoot的内置`Tomcat`的相关源码后再来继续分析`spring-boot-starter-web`的自动配置的源码。
14-
15-
因此,本篇我们来探究下**SpringBoot的启动流程是怎样的?**
10+
本篇我们来探究下**SpringBoot的启动流程是怎样的?**
1611
# 3 如何编写一个SpringBoot启动类
1712
我们都知道,我们运行一个SpringBoot项目,引入相关`Starters`和相关依赖后,再编写一个启动类,然后在这个启动类标上`@SpringBootApplication`注解,然后就可以启动运行项目了,如下代码:
1813
```java

‎SpringBoot/8 SpringApplication对象是如何构建的? SpringBoot源码(八).md renamed to ‎SpringBoot/4 SpringApplication对象是如何构建的? SpringBoot源码(四).md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
2-
本篇接 [SpringBoot的启动流程是怎样的?SpringBoot源码(七)](https://github.com/yuanmabiji/Java-SourceCode-Blogs/blob/master/SpringBoot/7%20SpringBoot%E7%9A%84%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E6%98%AF%E6%80%8E%E6%A0%B7%E7%9A%84%EF%BC%9FSpringBoot%E6%BA%90%E7%A0%81%EF%BC%88%E4%B8%83%EF%BC%89.md)
3-
41
# 1 温故而知新
52

63
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了**SpringBoot的启动流程**,现将关键步骤再浓缩总结下:
@@ -190,7 +187,7 @@ private Class<?> deduceMainApplicationClass() {
190187

191188
# 4 SpringBoot的SPI机制原理解读
192189

193-
由于SpringBoot的SPI机制是一个很重要的知识点,因此这里单独一小节来分析。我们都知道,SpringBoot没有使用Java的SPI机制(Java的SPI机制可以看看笔者的[Java是如何实现自己的SPI机制的?](https://juejin.im/post/5e7c26a76fb9a009a441757c),真的是干货满满),而是自定义实现了一套自己的SPI机制。SpringBoot利用自定义实现的SPI机制可以加载初始化器实现类,监听器实现类和自动配置类等等。如果我们要添加自动配置类或自定义监听器,那么我们很重要的一步就是在`spring.factories`中进行配置,然后才会被SpringBoot加载。
190+
由于SpringBoot的SPI机制是一个很重要的知识点,因此这里单独一小节来分析。我们都知道,SpringBoot没有使用Java的SPI机制(Java的SPI机制可以看看笔者的[Java是如何实现自己的SPI机制的?](https://juejin.im/post/5e7c26a76fb9a009a441757c),真的是干货满满),而是自定义实现了一套自己的SPI机制。SpringBoot利用自定义实现的SPI机制可以**加载初始化器实现类,监听器实现类和自动配置类**等等。如果我们要添加自动配置类或自定义监听器,那么我们很重要的一步就是在`spring.factories`中进行配置,然后才会被SpringBoot加载。
194191

195192
好了,那么接下来我们就来重点分析下**SpringBoot是如何是实现自己的SPI机制的**
196193

@@ -431,3 +428,8 @@ private <T> List<T> createSpringFactoriesInstances(Class<T> type,
431428

432429
注:该源码分析对应SpringBoot版本为**2.1.0.RELEASE**,本文对应的SpringBoot源码解析项目github地址:https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE
433430

431+
## 7 技术引用参考
432+
433+
+ [commaDelimitedListToStringArray](https://blog.csdn.net/weixin_30576859/article/details/95452202)
434+
435+
* [MultiValueMap](https://blog.csdn.net/zty1317313805/article/details/80096498)

‎SpringBoot/9 SpringBoot事件监听机制源码分析(上) SpringBoot源码(九).md renamed to ‎SpringBoot/5 SpringBoot事件监听机制源码分析(上) SpringBoot源码(五).md

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
**SpringBoot中文注释项目Github地址:**
2-
3-
https://github.com/yuanmabiji/spring-boot-2.1.0.RELEASE
4-
5-
6-
7-
本篇接 [SpringApplication对象是如何构建的? SpringBoot源码(八)](https://juejin.im/post/5e82bac9518825737a314096)
8-
91
# 1 温故而知新
102
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了**SpringApplication对象的构建过程及SpringBoot自己实现的一套SPI机制**,现将关键步骤再浓缩总结下:
113
1. `SpringApplication`对象的构造过程其实就是给`SpringApplication`类的**6**个成员变量赋值;
@@ -80,7 +72,7 @@ public ConfigurableApplicationContext run(String... args) {
8072
```
8173
可以看到SpringBoot在启动过程中首先会先新建一个`SpringApplicationRunListeners`对象用于发射SpringBoot启动过程中的各种生命周期事件,比如发射`ApplicationStartingEvent`,`ApplicationEnvironmentPreparedEvent``ApplicationContextInitializedEvent`等事件,然后相应的监听器会执行一些SpringBoot启动过程中的初始化逻辑。那么,监听这些SpringBoot的生命周期事件的监听器们是何时被加载实例化的呢?还记得上篇文章在分析`SpringApplication`的构建过程吗?没错,这些执行初始化逻辑的监听器们正是在`SpringApplication`的构建过程中根据`ApplicationListener`接口去`spring.factories`配置文件中加载并实例化的。
8274
# 3.1 为广播SpringBoot内置生命周期事件做前期准备
83-
# 3.1.1 加载ApplicationListener监听器实现类
75+
## 3.1.1 加载ApplicationListener监听器实现类
8476
我们再来回顾下[SpringApplication对象是如何构建的? SpringBoot源码(八)](https://juejin.im/post/5e82bac9518825737a314096)一文中讲到在构建`SpringApplication`对象时的`setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));`这句代码。
8577

8678
这句代码做的事情就是从`spring.factories`中加载出`ApplicationListener`事件监听接口的SPI扩展实现类然后添加到`SpringApplication`对象的`listeners`集合中,用于后续监听SpringBoot启动过程中的事件,来执行一些初始化逻辑工作。
@@ -94,7 +86,7 @@ SpringBoot启动时的具体监听器们都实现了`ApplicationListener`接口
9486

9587
![](https://user-gold-cdn.xitu.io/2020/4/13/17170eb8ae034bbd?w=712&h=584&f=png&s=53731)
9688

97-
# 3.1.2 加载SPI扩展类EventPublishingRunListener
89+
## 3.1.2 加载SPI扩展类EventPublishingRunListener
9890
前面讲到,在SpringBoot的启动过程中首先会先新建一个`SpringApplicationRunListeners`对象用于发射SpringBoot启动过程中的生命周期事件,即我们现在来看下`SpringApplicationRunListeners listeners = getRunListeners(args);`这句代码:
9991

10092
```java
@@ -116,7 +108,7 @@ private SpringApplicationRunListeners getRunListeners(String[] args) {
116108

117109
![](https://user-gold-cdn.xitu.io/2020/4/18/1718d054c88bebb9?w=692&h=117&f=png&s=13088)
118110
由上图可以看到,`SpringApplicationRunListener`只有`EventPublishingRunListener`这个SPI实现类
119-
`EventPublishingRunListener`这个哥们在SpringBoot的启动过程中尤其重要,由其在SpringBoot启动过程的不同阶段发射不同的SpringBoot的生命周期事件,**`SpringApplicationRunListeners`对象没有承担广播事件的职责,而最终是委托`EventPublishingRunListener`这个哥们来广播事件的。**
111+
`EventPublishingRunListener`这个哥们在SpringBoot的启动过程中尤其重要,尤其在SpringBoot启动过程的不同阶段发射不同的SpringBoot的生命周期事件,**`SpringApplicationRunListeners`对象没有承担广播事件的职责,而最终是委托`EventPublishingRunListener`这个哥们来广播事件的。**
120112

121113
因为从`spring.factories`中加载`EventPublishingRunListener`类后还会实例化该类,那么我们再跟进`EventPublishingRunListener`的源码,看看其是如何承担发射SpringBoot生命周期事件这一职责的?
122114
```java
@@ -263,7 +255,7 @@ public EventPublishingRunListener(SpringApplication application, String[] args)
263255
可以看到在`EventPublishingRunListener`的构造函数中有一个`for`循环会遍历之前从`spring.factories`中加载的监听器们,然后添加到集合中缓存起来,用于以后广播各种事件时直接从这个集合中取出来即可,而不用再去`spring.factories`中加载,提高效率。
264256

265257
# 3.2 广播SpringBoot的内置生命周期事件
266-
`spring.factories`配置文件中加载并实例化`EventPublishingRunListener`对象后,那么在在SpringBoot的启动过程中会发射一系列SpringBoot内置的生命周期事件,我们再来回顾下SpringBoot启动过程中的源码:
258+
`spring.factories`配置文件中加载并实例化`EventPublishingRunListener`对象后,那么在SpringBoot的启动过程中会发射一系列SpringBoot内置的生命周期事件,我们再来回顾下SpringBoot启动过程中的源码:
267259
```java
268260
// SpringApplication.java
269261

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /