Skip to content

Commit 6cdcf00

Browse files
committed
9.15
1 parent 0d98e38 commit 6cdcf00

7 files changed

+51
-136
lines changed

docs/java-web/Spring/Spring源码剖析1:Spring概述.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
* [为什么需要Spring及Spring的优点](#为什么需要spring及spring的优点)
77
* [如何学好Spring](#如何学好spring)
88

9-
10-
原文出处: [张开涛](http://sishuok.com/forum/blogPost/list/0/2508.html)
9+
> 原文出处: [张开涛](http://sishuok.com/forum/blogPost/list/0/2508.html)
1110
1211

1312

docs/java-web/Spring/Spring源码剖析2:初探Spring IOC核心流程.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
接下来的文章会更加深入剖析Bean容器如何解析xml,注册和初始化bean,以及如何获取bean实例等详细的过程。
1717

18-
转自:[http://www.importnew.com/19243.html](http://www.importnew.com/19243.html)
18+
> 转自:[http://www.importnew.com/19243.html](http://www.importnew.com/19243.html)
1919
2020
1\. 初始化
2121

@@ -37,7 +37,7 @@
3737
```
3838

3939
加载时需要读取、解析、注册bean,这个过程具体的调用栈如下所示:
40-
[![](https://cloud.githubusercontent.com/assets/1736354/7896285/8a488060-06e6-11e5-9ad9-4ddd3375984f.png "load")](https://cloud.githubusercontent.com/assets/1736354/7896285/8a488060-06e6-11e5-9ad9-4ddd3375984f.png "load")
40+
![](https://cloud.githubusercontent.com/assets/1736354/7896285/8a488060-06e6-11e5-9ad9-4ddd3375984f.png )
4141

4242
下面对每一步的关键的代码进行详细分析:
4343

@@ -46,7 +46,7 @@
4646
保存配置位置,并刷新
4747
在调用ClassPathXmlApplicationContext后,先会将配置位置信息保存到configLocations,供后面解析使用,之后,会调用`AbstractApplicationContext`的refresh方法进行刷新:
4848

49-
```
49+
```java
5050
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh,
5151
ApplicationContext parent) throws BeansException {
5252

@@ -101,7 +101,7 @@ public void refresh() throws BeansException, IllegalStateException {
101101

102102
创建载入BeanFactory
103103

104-
```
104+
```java
105105
protected final void refreshBeanFactory() throws BeansException {
106106
// ... ...
107107
DefaultListableBeanFactory beanFactory = createBeanFactory();
@@ -113,7 +113,7 @@ protected final void refreshBeanFactory() throws BeansException {
113113

114114
创建XMLBeanDefinitionReader
115115

116-
```
116+
```java
117117
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
118118
throws BeansException, IOException {
119119
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
@@ -129,7 +129,7 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
129129

130130
创建处理每一个resource
131131

132-
```
132+
```java
133133
public int loadBeanDefinitions(String location, Set<Resource> actualResources)
134134
throws BeanDefinitionStoreException {
135135
// ... ...
@@ -152,7 +152,7 @@ public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStore
152152

153153
处理XML每个元素
154154

155-
```
155+
```java
156156
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
157157
// ... ...
158158
NodeList nl = root.getChildNodes();
@@ -175,7 +175,7 @@ protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate d
175175

176176
解析和注册bean
177177

178-
```
178+
```java
179179
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
180180
// 解析
181181
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
@@ -201,11 +201,11 @@ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate d
201201

202202
## 解析
203203

204-
[![](https://cloud.githubusercontent.com/assets/1736354/7896302/eae02bc6-06e6-11e5-941a-d1f59e3b363f.png "process")](https://cloud.githubusercontent.com/assets/1736354/7896302/eae02bc6-06e6-11e5-941a-d1f59e3b363f.png "process")
204+
![](https://cloud.githubusercontent.com/assets/1736354/7896302/eae02bc6-06e6-11e5-941a-d1f59e3b363f.png)
205205

206206
处理每个Bean的元素
207207

208-
```
208+
```java
209209
public AbstractBeanDefinition parseBeanDefinitionElement(
210210
Element ele, String beanName, BeanDefinition containingBean) {
211211

@@ -230,7 +230,7 @@ public AbstractBeanDefinition parseBeanDefinitionElement(
230230

231231
处理属性的值
232232

233-
```
233+
```java
234234
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
235235
String elementName = (propertyName != null) ?
236236
"<property> element for property '" + propertyName + "'" :
@@ -264,7 +264,7 @@ public Object parsePropertyValue(Element ele, BeanDefinition bd, String property
264264

265265
1.4 注册
266266

267-
```
267+
```java
268268
public static void registerBeanDefinition(
269269
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
270270
throws BeanDefinitionStoreException {
@@ -299,7 +299,7 @@ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinitio
299299

300300
## 注册
301301

302-
```
302+
```java
303303
public static void registerBeanDefinition(
304304
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
305305
throws BeanDefinitionStoreException {
@@ -338,19 +338,19 @@ public void registerBeanDefinition(String beanName, BeanDefinition beanDefinitio
338338
### 注入依赖
339339

340340
当完成初始化IOC容器后,如果bean没有设置lazy-init(延迟加载)属性,那么bean的实例就会在初始化IOC完成之后,及时地进行初始化。初始化时会先建立实例,然后根据配置利用反射对实例进行进一步操作,具体流程如下所示:
341-
[![](https://cloud.githubusercontent.com/assets/1736354/7929429/615570ea-0930-11e5-8097-ae982ef7709d.png "bean_flow")](https://cloud.githubusercontent.com/assets/1736354/7929429/615570ea-0930-11e5-8097-ae982ef7709d.png "bean_flow")
341+
![](https://cloud.githubusercontent.com/assets/1736354/7929429/615570ea-0930-11e5-8097-ae982ef7709d.png)
342342

343343
创建bean的实例
344344
创建bean的实例过程函数调用栈如下所示:
345-
[![](https://cloud.githubusercontent.com/assets/1736354/7929379/cec01bcc-092f-11e5-81ad-88c285f33845.png "create_bean")](https://cloud.githubusercontent.com/assets/1736354/7929379/cec01bcc-092f-11e5-81ad-88c285f33845.png "create_bean")
345+
![](https://cloud.githubusercontent.com/assets/1736354/7929379/cec01bcc-092f-11e5-81ad-88c285f33845.png)
346346

347347
注入bean的属性
348348
注入bean的属性过程函数调用栈如下所示:
349-
[![](https://cloud.githubusercontent.com/assets/1736354/7929381/db58350e-092f-11e5-82a4-caaf349291ea.png "inject_property")](https://cloud.githubusercontent.com/assets/1736354/7929381/db58350e-092f-11e5-82a4-caaf349291ea.png "inject_property")
349+
![](https://cloud.githubusercontent.com/assets/1736354/7929381/db58350e-092f-11e5-82a4-caaf349291ea.png)
350350

351351
在创建bean和注入bean的属性时,都是在doCreateBean函数中进行的,我们重点看下:
352352

353-
```
353+
```java
354354
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
355355
final Object[] args) {
356356
// Instantiate the bean.

docs/java-web/Spring/Spring源码剖析4:懒加载的单例Bean获取过程分析.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,7 @@
55
* [step2:](#step2)
66
* [step3 : 我们已经step by step 的看到了如何将xml文件转换成Document的,现在就要分析是如何提取和注册bean的。](#step3--我们已经step-by-step-的看到了如何将xml文件转换成document的,现在就要分析是如何提取和注册bean的。)
77

8-
9-
本文转自五月的仓颉 https://www.cnblogs.com/xrq730
10-
11-
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
12-
> https://github.com/h2pl/Java-Tutorial
13-
14-
喜欢的话麻烦点下Star哈
15-
16-
文章将同步到我的个人博客:
17-
> www.how2playlife.com
18-
19-
本文是微信公众号【Java技术江湖】的《Spring和SpringMVC源码分析》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。
20-
21-
该系列博文会告诉你如何从spring基础入手,一步步地学习spring基础和springmvc的框架知识,并上手进行项目实战,spring框架是每一个Java工程师必须要学习和理解的知识点,进一步来说,你还需要掌握spring甚至是springmvc的源码以及实现原理,才能更完整地了解整个spring技术体系,形成自己的知识框架。
22-
23-
后续还会有springboot和springcloud的技术专题,陆续为大家带来,敬请期待。
24-
25-
为了更好地总结和检验你的学习成果,本系列文章也会提供部分知识点对应的面试题以及参考答案。
26-
27-
如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。
28-
29-
<!-- more -->
8+
> 本文转自五月的仓颉 https://www.cnblogs.com/xrq730
309
3110
## 前言
3211

docs/java-web/Spring/Spring源码剖析5:JDK和cglib动态代理原理详解.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反
8181

8282
### Proxy类中的newProxyInstance
8383

84-
```
84+
```java
8585
public static Object newProxyInstance(ClassLoader loader,
8686
Class<?>[] interfaces,
8787
InvocationHandler h)
@@ -141,9 +141,9 @@ JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反
141141

142142
所以代理类其实是通过getProxyClass方法来生成的:
143143

144-
```
145-
/**
146-
* 生成一个代理类,但是在调用本方法之前必须进行权限检查
144+
```java
145+
/**
146+
* 生成一个代理类,但是在调用本方法之前必须进行权限检查
147147
*/
148148
private static Class<?> getProxyClass0(ClassLoader loader,
149149
Class<?>... interfaces) {
@@ -161,7 +161,7 @@ JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反
161161

162162
那么ProxyClassFactory是什么呢?
163163

164-
```
164+
```java
165165
/**
166166
* 里面有一个根据给定ClassLoader和Interface来创建代理类的工厂函数
167167
*
@@ -270,7 +270,7 @@ JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反
270270

271271
由上方代码byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);可以看到,其实生成代理类字节码文件的工作是通过 ProxyGenerate类中的generateProxyClass方法来完成的。
272272

273-
```
273+
```java
274274
public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
275275
ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
276276
// 真正用来生成代理类字节码文件的方法在这里
@@ -307,7 +307,7 @@ JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反
307307

308308
下面来看看真正用于生成代理类字节码文件的generateClassFile方法:
309309

310-
```
310+
```java
311311
private byte[] generateClassFile() {
312312
//下面一系列的addProxyMethod方法是将接口中的方法和Object中的方法添加到代理方法中(proxyMethod)
313313
this.addProxyMethod(hashCodeMethod, Object.class);
@@ -432,7 +432,7 @@ private byte[] generateClassFile() {
432432

433433
下面是将接口与Object中一些方法添加到代理类中的addProxyMethod方法:
434434

435-
```
435+
```java
436436
private void addProxyMethod(Method var1, Class<?> var2) {
437437
String var3 = var1.getName();//获得方法名称
438438
Class[] var4 = var1.getParameterTypes();//获得方法参数类型
@@ -465,23 +465,23 @@ private void addProxyMethod(Method var1, Class<?> var2) {
465465

466466
这就是最终真正的代理类,它继承自Proxy并实现了我们定义的Subject接口。我们通过
467467

468-
```
468+
```java
469469
HelloInterface helloInterface = (HelloInterface ) Proxy.newProxyInstance(loader, interfaces, handler);
470470
```
471471

472472
* 1
473473

474474
得到的最终代理类对象就是上面这个类的实例。那么我们执行如下语句:
475475

476-
```
476+
```java
477477
helloInterface.hello("Tom");
478478
```
479479

480480
* 1
481481

482482
实际上就是执行上面类的相应方法,也就是:
483483

484-
```
484+
```java
485485
public final void hello(String paramString)
486486
{
487487
try
@@ -503,13 +503,13 @@ helloInterface.hello("Tom");
503503

504504
注意这里的`this.h.invoke`中的h,它是类Proxy中的一个属性
505505

506-
```
506+
```java
507507
protected InvocationHandler h;
508508
```
509509

510510
因为这个代理类继承了Proxy,所以也就继承了这个属性,而这个属性值就是我们定义的
511511

512-
```
512+
```java
513513
InvocationHandler handler = new InvocationHandlerImpl(hello);
514514
```
515515

@@ -576,7 +576,7 @@ JDK代理要求被代理的类必须实现接口,有很强的局限性。而CG
576576

577577
我们来看看将代理类Class文件反编译之后的Java代码
578578

579-
```
579+
```java
580580
package proxy;
581581

582582
import java.lang.reflect.Method;

0 commit comments

Comments
 (0)