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

Appearance settings

Commit dcacc8a

Browse filesBrowse files
committed
Merge branch 'master' of github.com:coderbruis/JavaSourceCodeLearning into master
2 parents 40dd726 + d3086ad commit dcacc8a
Copy full SHA for dcacc8a

File tree

Expand file treeCollapse file tree

26 files changed

+279
-279
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

26 files changed

+279
-279
lines changed
Open diff view settings
Collapse file

‎note/Dubbo/Dubbo底层源码学习——服务暴露.md‎

Copy file name to clipboardExpand all lines: note/Dubbo/Dubbo底层源码学习——服务暴露.md
+4-4Lines changed: 4 additions & 4 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
```
1+
```Java
22
package org.apache.dubbo.rpc;
33
import org.apache.dubbo.common.extension.ExtensionLoader;
44
public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
@@ -33,7 +33,7 @@ public class Protocol$Adaptive implements org.apache.dubbo.rpc.Protocol {
3333
}
3434
```
3535

36-
```
36+
```Java
3737
package org.apache.dubbo.rpc;
3838
import org.apache.dubbo.common.extension.ExtensionLoader;
3939
public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory {
@@ -71,7 +71,7 @@ public class ProxyFactory$Adaptive implements org.apache.dubbo.rpc.ProxyFactory
7171
}
7272
```
7373

74-
```
74+
```Java
7575
package org.apache.dubbo.remoting;
7676
import org.apache.dubbo.common.extension.ExtensionLoader;
7777
public class Transporter$Adaptive implements org.apache.dubbo.remoting.Transporter {
@@ -99,7 +99,7 @@ public class Transporter$Adaptive implements org.apache.dubbo.remoting.Transport
9999
![export01](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/images/Dubbo/export01.png)
100100

101101
JavassistProxyFactory代码如下:
102-
```
102+
```Java
103103
public class JavassistProxyFactory extends AbstractProxyFactory {
104104

105105
@Override
Collapse file

‎note/Dubbo/Dubbo底层源码学习(一)—— Dubbo的URL.md‎

Copy file name to clipboardExpand all lines: note/Dubbo/Dubbo底层源码学习(一)—— Dubbo的URL.md
+1-1Lines changed: 1 addition & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ dubbo://172.17.32.91:20880/org.apache.dubbo.demo.DemoService?anyhost=true&applic
3434

3535
先看下Dubbo中org.apache.dubbo.common包下的URL类源码:
3636

37-
```
37+
```Java
3838
public /*final**/
3939
class URL implements Serializable {
4040

Collapse file

‎note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(上).md‎

Copy file name to clipboardExpand all lines: note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(上).md
+7-7Lines changed: 7 additions & 7 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ Java SPI的定义及使用步骤如下:
2828
在com.test.spi包目录下,定义了一个PrintService接口和一个PrintServiceImpl实现类,然后在resources目录下定义了一个META-INF/services/com.test.spi.PrintService,注意这里定义的是一个
2929
全路径名称的文件。
3030

31-
```
31+
```Java
3232
public interface Printservice (
3333
void printlnfo();
3434
}
3535
```
3636

37-
```
37+
```Java
3838
public class PrintServicelmpl implements Printservice {
3939
@Override
4040
public void printlnfo() {
@@ -43,7 +43,7 @@ public class PrintServicelmpl implements Printservice {
4343
}
4444
```
4545

46-
```
46+
```Java
4747
public static void main(String[] args) (
4848
ServiceLoader<PrintService> serviceServiceLoader =
4949
ServiceLoader.load(PrintService.class);
@@ -119,7 +119,7 @@ ExtensionLoader即扩展点加载器,它是Dubbo SPI的核心,负责加载
119119

120120
上图清楚的展示了LoadingStrategy接口及其实现类的关系。LoadingStrategy继承了Prioritized,因而其实现类会有优先级之分,而Dubbo默认是使用的DubboInternalLoadingStrategy,查看其三个类的源码:
121121

122-
```
122+
```Java
123123
public class DubboInternalLoadingStrategy implements LoadingStrategy {
124124

125125
// 表示要加载的目录位置
@@ -136,7 +136,7 @@ public class DubboInternalLoadingStrategy implements LoadingStrategy {
136136
}
137137
```
138138

139-
```
139+
```Java
140140
public class DubboLoadingStrategy implements LoadingStrategy {
141141

142142
// 表示要加载的目录位置
@@ -160,7 +160,7 @@ public class DubboLoadingStrategy implements LoadingStrategy {
160160
}
161161
```
162162

163-
```
163+
```Java
164164
public class ServicesLoadingStrategy implements LoadingStrategy {
165165

166166
// 表示要加载的目录位置
@@ -185,7 +185,7 @@ public class ServicesLoadingStrategy implements LoadingStrategy {
185185

186186
这里的MAX_PRIORITYNORMAL_PRIORITYMIN_PRIORITY时定义在Prioritized这个接口中的,查看一下Prioritized中定义的值以及实现的compareTo方法:
187187

188-
```
188+
```Java
189189
/**
190190
* The maximum priority
191191
*/
Collapse file

‎note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(下).md‎

Copy file name to clipboardExpand all lines: note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(下).md
+14-14Lines changed: 14 additions & 14 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
另外在@SPI注解的value值指定了扩展点默认的实现类名,例如SimpleExt注解由@SPI("impl1")修饰,则表示它的实现类名为:SimpleExtImpl1,查看SPI的配置文件可证:
1414

15-
```
15+
```Java
1616
# Comment 1
1717
impl1=org.apache.dubbo.common.extension.ext1.impl.SimpleExtImpl1#Hello World
1818
impl2=org.apache.dubbo.common.extension.ext1.impl.SimpleExtImpl2 # Comment 2
@@ -24,13 +24,13 @@ Dubbo通过ExtensionLoader去加载上述SPI配置文件,然后读取到@SPI("
2424
Dubbo SPI的核心逻辑几乎都封装在ExtensionLoader之中,ExtensionLoader存放于dubbo-common模块的extension保重,功能类似于JDK SPI中的java.util.ServiceLoader。
2525

2626
下面展示了ExtensionLoader最常用的使用方式:
27-
```
27+
```Java
2828
SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultExtension();
2929
```
3030

3131
首先时调用ExtensionLoader#getExtensionLoader(SimpleExt.class),来获取SimpleExt类型的ExtensionLoader。查看ExtensionLoader源码如下:
3232

33-
```
33+
```Java
3434
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
3535
if (type == null) {
3636
throw new IllegalArgumentException("Extension type == null");
@@ -51,11 +51,11 @@ SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultEx
5151
}
5252
return loader;
5353
}
54-
```
54+
```Java
5555
getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经缓存了该类型的扩展点加载器,如果没有则new一个该类型的ExtensionLoader并添加进EXTENSION_LOADERS中。但需要注意的是ExtensionLoader的构造方法
5656
中,是会先创建默认的ExtensionFactory类型的ExtensionLoader对象,然后调用getAdaptiveExtension()方法创建适配类型的扩展点实现类。
5757

58-
```
58+
```Java
5959
private ExtensionLoader(Class<?> type) {
6060
this.type = type;
6161
// 从此处可以知道,对于默认的ExtensionFactory.class来说,是没有objectFactory熟悉对象值的
@@ -68,7 +68,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
6868
被赋值为AdaptiveExtensionFactory。
6969

7070
下面看下getExtensionClass()方法的逻辑
71-
```
71+
```Java
7272
private Class<?> getExtensionClass(String name) {
7373
if (type == null) {
7474
throw new IllegalArgumentException("Extension type == null");
@@ -81,7 +81,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
8181
}
8282
```
8383

84-
```
84+
```Java
8585
private Map<String, Class<?>> getExtensionClasses() {
8686
Map<String, Class<?>> classes = cachedClasses.get();
8787
// 双重检测,防止并发环境下指令重排序,cachedClasses是static类型
@@ -99,7 +99,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
9999
}
100100
```
101101

102-
```
102+
```Java
103103
private Map<String, Class<?>> loadExtensionClasses() {
104104
// 缓存默认的扩展点名称,这里会去读取@SPI注解
105105
cacheDefaultExtensionName();
@@ -140,7 +140,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
140140
}
141141
```
142142

143-
```
143+
```Java
144144
// 加载SPI配置文件目录
145145
private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
146146
boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
@@ -173,7 +173,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
173173
}
174174
```
175175

176-
```
176+
```Java
177177
private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
178178
boolean overridden) throws NoSuchMethodException {
179179
if (!type.isAssignableFrom(clazz)) {
@@ -218,7 +218,7 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
218218
![SPI_ADAPTIVE](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/images/Dubbo/spi_@Adaptive.png)
219219

220220
在ExtensionFactory接口上有@SPI注解修饰,而Dubbo会在调用ExtensionFactory时,会去调用ExtensionFactory的SPI配置文件中的扩展点名称以及扩展点实现类,查看下其SPI配置文件:
221-
```
221+
```Java
222222
adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
223223
spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory
224224
```
@@ -232,7 +232,7 @@ AdaptiveExtensionFactory会根据运行时状态来决定给ExtensionFactory赋
232232

233233
下面看下AdaptiveExtensionFactory类:
234234

235-
```
235+
```Java
236236
@Adaptive
237237
public class AdaptiveExtensionFactory implements ExtensionFactory {
238238

@@ -275,7 +275,7 @@ public class AdaptiveExtensionFactory implements ExtensionFactory {
275275

276276

277277
下面看看ExtensionLoader的方法:
278-
```
278+
```Java
279279
private Class<?> getAdaptiveExtensionClass() {
280280
// 获取扩展点实现类,如果缓存中没有则去扫描SPI文件,扫描到扩展点实现类后则存入cachedClasses缓存中
281281
getExtensionClasses(); // ------------------------ ②
@@ -325,7 +325,7 @@ public class AdaptiveExtensionFactory implements ExtensionFactory {
325325
的扩展点实现类,就会去通过Javassist来生成代理代码,即生成对于的Xxx@Adaptive代码。
326326

327327
下面就是通过Javassist代理生产的适配类。(再Dubbo源码中的dubbo-common模块test目录下的org.apache.dubbo.extension包中有对应的测试类)
328-
```
328+
```Java
329329
package org.apache.dubbo.common.extension.ext1;
330330

331331
import org.apache.dubbo.common.extension.ExtensionLoader;
Collapse file

‎note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(中).md‎

Copy file name to clipboardExpand all lines: note/Dubbo/Dubbo底层源码学习(二)—— Dubbo的SPI机制(中).md
+1-1Lines changed: 1 addition & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
接下来的原理分析通过Dubbo源码中的test包下的代码来进行说明。(想学好开源框架,要好好利用开源框架中各种Test用例)
6767

68-
```
68+
```Java
6969
@Test
7070
public void test_getDefaultExtension() throws Exception {
7171
SimpleExt ext = getExtensionLoader(SimpleExt.class).getDefaultExtension();
Collapse file

‎note/JDK/一篇文章快速深入学习ThreadLocal.md‎

Copy file name to clipboardExpand all lines: note/JDK/一篇文章快速深入学习ThreadLocal.md
+5-5Lines changed: 5 additions & 5 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
#### 2.1 ThreadLocal内部使用了哪些数据结构?
109109
首先,我们来看下ThreadLocal中几个比较重要的数据结构。
110110

111-
```
111+
```Java
112112
/**
113113
* 用于ThreadLocal内部ThreadLocalMap数据结构的哈希值,用于降低哈希冲突。
114114
*/
@@ -135,7 +135,7 @@ private static int nextHashCode() {
135135

136136
下面将是ThreadLocal最终要的一个数据结构:ThreadLocalMap
137137

138-
```
138+
```Java
139139
/**
140140
* ThreadLocalMap其实就是一个用于ThreadLocal的自定义HashMap,它和HashMap很像。在其内部有一个自定义的Entry类,
141141
* 并且有一个Entry数组来存储这个类的实例对象。类似于HashMap,ThreadLocalMap同样的拥有初始大小,拥有扩容阈值。
@@ -197,7 +197,7 @@ static class ThreadLocalMap {
197197

198198
下面回到关于ThreadLocal源码的介绍,先看看set()和get()方法源码:
199199

200-
```
200+
```Java
201201
// ThreadLocal中的set()方法
202202
public void set(T value) {
203203
Thread t = Thread.currentThread();
@@ -244,7 +244,7 @@ static class ThreadLocalMap {
244244

245245

246246

247-
```
247+
```Java
248248
public T get() {
249249
// 获取当前线程
250250
Thread t = Thread.currentThread();
@@ -280,7 +280,7 @@ static class ThreadLocalMap {
280280

281281
知道怎么存储以及获取ThreadLocal之后,还要知道怎么清除ThreadLocal,防止内存泄漏,下面看下remove()源码:
282282

283-
```
283+
```Java
284284
// ThreadLocal的remove()方法
285285
public void remove() {
286286
// 获取当前线程中的ThreadLocalMap
Collapse file

‎note/JDK/深入学习Java volatile关键字.md‎

Copy file name to clipboardExpand all lines: note/JDK/深入学习Java volatile关键字.md
+4-4Lines changed: 4 additions & 4 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Lock引起的将当前处理器缓存该变量的数据写回到系统内存中
5656
为了实现volatile的内存语义,编译期在生成字节码时会对使用volatile关键字修饰的变量进行处理,在字节码文件里对应位置生成一个Lock前缀指令,Lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成。
5757

5858
下面代码来演示一下禁止指令重排序:
59-
```
59+
```Java
6060
a = 1; //语句一
6161
b = 2; //语句二
6262
flag = true; //语句三,flag为volatile变量
@@ -137,7 +137,7 @@ LoadLoad,StoreStore,LoadStore,StoreLoad实际上是Java对上面两种屏障的
137137
138138
下面来谈谈volatile的应用场景:
139139
1. 状态标志:多个线程以一个volatile变量作为为状态标志,例如完成**初始化**或者**状态同步**。典型例子AQS的同步状态:
140-
```
140+
```Java
141141
/**
142142
* The synchronization state.
143143
*/
@@ -146,7 +146,7 @@ private volatile int state;
146146
2. 一次性安全发布
147147

148148
最典型的例子就是安全的单例模式:
149-
```
149+
```Java
150150
private static Singleton instance;
151151
public static Singleton getInstance() {
152152
//第一次null检查
@@ -164,7 +164,7 @@ public static Singleton getInstance() {
164164
上面这种写法,仍然会出现问题——多线程调用getInstance方法时,有可能一个线程会获得还**没有初始化的对象**!这都是因为重排序的原因,具体分析这里不展开。
165165

166166
解决办法及时用volatile对instance进行修饰
167-
```
167+
```Java
168168
private static volatile Singleton instance;
169169
```
170170
这就是经典的“双重检查锁定与延迟初始化”。

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.