-
Notifications
You must be signed in to change notification settings - Fork 1
/
dubbo3-spi.drawio
753 lines (753 loc) · 121 KB
/
dubbo3-spi.drawio
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
<mxfile host="Electron" modified="2024-01-13T07:05:23.788Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.5 Chrome/114.0.5735.243 Electron/25.3.1 Safari/537.36" etag="nOErsT5vRUinCOw11oH4" version="21.6.5" type="device">
<diagram name="Dubbo-SPI-SRC" id="UC6zfxpho-fM6Mz8ni64">
<mxGraphModel dx="3088" dy="879" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="nFbYhWVqmTEnoM216xpz-1" value="<h1 style="font-size: 16px;"><font style="font-size: 16px;">Dubbo SPI 工作原理 </font><font style="font-size: 16px; font-weight: normal;">(3.2.9)</font></h1><p style="font-size: 10px;">SPI机制在框架中应用还是非常常见的,这里打算详细研究一下Dubbo SPI实现。官方文档:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/spi/<br style="border-color: var(--border-color); font-size: 12px;">对比一下JDK SPI 还 Dubbo SPI 的优缺点。<br>源码位于:dubbo-common/src/main/java/org/apache/dubbo/common/extension, (代码量3K行)官方还提供了丰富的单元测试。<br><span style="background-color: initial;">可以从官方单元测试 ExtensionDirectorTest#testInheritanceAndScope()&nbsp; 入手;<br>以 Dubbo SPI 加载 ProxyFactory 为例。</span><br></p>" style="text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;" parent="1" vertex="1">
<mxGeometry x="40" y="10" width="720" height="90" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-2" target="nFbYhWVqmTEnoM216xpz-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-2" value="ExtensionDirectorTest#<br style="font-size: 10px;">testInheritanceAndScope()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="40" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-3" value="<div style="text-align: center;"><b>ExtensionAccessor (I)</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">ExtensionDirector getExtensionDirector();<br></p><p style="margin: 0px 0px 0px 4px;">&lt;T&gt; ExtensionLoader&lt;T&gt; getExtensionLoader(Class&lt;T&gt; type);<br></p><p style="margin: 0px 0px 0px 4px;">&lt;T&gt; T getExtension(Class&lt;T&gt; type, String name);<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//获取自适应拓展类型</font></p><p style="margin: 0px 0px 0px 4px;">&lt;T&gt; T getAdaptiveExtension(Class&lt;T&gt; type);<br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//</font></p><p style="margin: 0px 0px 0px 4px;">&lt;T&gt; T getDefaultExtension(Class&lt;T&gt; type)<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-480" y="480" width="440" height="120" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-5" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;dashed=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-4" target="nFbYhWVqmTEnoM216xpz-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-7" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-4" target="nFbYhWVqmTEnoM216xpz-6" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-4" value="<div style="text-align: center;"><b>ExtensionDirector</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><span style="background-color: initial;">ExtensionLoader的管理器</span><br></p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类 -&gt; ExtensionLoader, ExtensionLoader缓存</font></p><p style="margin: 0px 0px 0px 4px;">private final ConcurrentMap&lt;Class&lt;?&gt;, ExtensionLoader&lt;?&gt;&gt; <b>extensionLoadersMap</b> = new ConcurrentHashMap&lt;&gt;(64);</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类 -&gt; ExtensionScope</font></p><p style="margin: 0px 0px 0px 4px;">private final ConcurrentMap&lt;Class&lt;?&gt;, ExtensionScope&gt; <b>extensionScopeMap</b> = new ConcurrentHashMap&lt;&gt;(64);</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//父管理器,</font></p><p style="margin: 0px 0px 0px 4px;">private final ExtensionDirector <b>parent</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展分享范围, FRAMEWORK APPLICATION MODULE SELF</font></p><p style="margin: 0px 0px 0px 4px;">private final ExtensionScope <b>scope</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展后置处理器,for ???</font></p><p style="margin: 0px 0px 0px 4px;">private final List&lt;ExtensionPostProcessor&gt; <b>extensionPostProcessors</b> = new ArrayList&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//模型对象,做什么用的?</font></p><p style="margin: 0px 0px 0px 4px;">private final ScopeModel <b>scopeModel</b>;</p><p style="margin: 0px 0px 0px 4px;">private final AtomicBoolean destroyed = new AtomicBoolean();</p><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-480" y="640" width="440" height="280" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-117" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-6" target="334U5BKtB8SHjy518kIA-100" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-6" value="<div style="text-align: center;"><b>ExtensionLoader</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><span style="background-color: initial;">拓展类加载器,与拓展接口类一一对应</span><br></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;"><br></span></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");</span><br></p><p style="margin: 0px 0px 0px 4px;">private static final String SPECIAL_SPI_PROPERTIES = "special_spi.properties";</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//已加载的类型(type的子类)和实例</font></p><p style="margin: 0px 0px 0px 4px;">private final ConcurrentMap&lt;Class&lt;?&gt;, Object&gt; <b>extensionInstances</b> = new ConcurrentHashMap&lt;&gt;(64);</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//加载的目标类型</font></p><p style="margin: 0px 0px 0px 4px;">private final Class&lt;?&gt; <b>type</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//自适应的ExtensionInjector实例,用于给type类实例属性注入值</font></p><p style="margin: 0px 0px 0px 4px;">private final ExtensionInjector <b>injector</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类-&gt;拓展类名</font></p><p style="margin: 0px 0px 0px 4px;">private final ConcurrentMap&lt;Class&lt;?&gt;, String&gt; <b>cachedNames</b> = new ConcurrentHashMap&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//加载的类型(除了@Adaptive 和 wrapper class, 这两种有专门的缓存位置 cachedAdaptiveClass cachedWrapperClasses</font><font color="#007fff">)</font></p><p style="margin: 0px 0px 0px 4px;">private final Holder&lt;Map&lt;String, Class&lt;?&gt;&gt;&gt; <b>cachedClasses</b> = new Holder&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类名 -&gt; Activate注解实例,首次加载接口类时缓存</font></p><p style="margin: 0px 0px 0px 4px;">private final Map&lt;String, Object&gt; <b>cachedActivates</b> = Collections.synchronizedMap(new LinkedHashMap&lt;&gt;());</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类名 -&gt; Activate groups</font></p><p style="margin: 0px 0px 0px 4px;">private final Map&lt;String, Set&lt;String&gt;&gt; <b>cachedActivateGroups</b> = Collections.synchronizedMap(new LinkedHashMap&lt;&gt;());</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//拓展类名 -&gt; Activate values</font><br></p><p style="margin: 0px 0px 0px 4px;">private final Map&lt;String, String[][]&gt; <b>cachedActivateValues</b> = Collections.synchronizedMap(new LinkedHashMap&lt;&gt;());</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//加载的拓展类的实例Holder,不包括自适应拓展类的实例</font></p><p style="margin: 0px 0px 0px 4px;">private final ConcurrentMap&lt;String, Holder&lt;Object&gt;&gt; <b>cachedInstances</b> = new ConcurrentHashMap&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//缓存已加载的自适应的拓展类的实例</font></p><p style="margin: 0px 0px 0px 4px;">private final Holder&lt;Object&gt; <b>cachedAdaptiveInstance</b> = new Holder&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//缓存已加载的自适应拓展类, 这里可以看到每种接口类型的自适应拓展类只有一个</font><br></p><p style="margin: 0px 0px 0px 4px;">private volatile Class&lt;?&gt; <b>cachedAdaptiveClass</b> = null;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//默认实现类名,@SPI中指定,对应SPI文件中的key</font></p><p style="margin: 0px 0px 0px 4px;">private String <b>cachedDefaultName</b>;</p><p style="margin: 0px 0px 0px 4px;">private volatile Throwable createAdaptiveInstanceError;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//加载的 wrapper class 类型,&nbsp; 比如 APlus(A a)&nbsp; APlus 就是 A 的 wrapper class</font></p><p style="margin: 0px 0px 0px 4px;">private Set&lt;Class&lt;?&gt;&gt; <b>cachedWrapperClasses</b>;</p><p style="margin: 0px 0px 0px 4px;">private final Map&lt;String, IllegalStateException&gt; exceptions = new ConcurrentHashMap&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//加载策略列表,加载优先级从高到底依次是:DubboInternalLoadingStrategy DubboExternalLoadingStrategy&nbsp;<br>DubboLoadingStrategy ServicesLoadingStrategy</font></p><p style="margin: 0px 0px 0px 4px;">private static volatile LoadingStrategy[] <b>strategies</b> = loadLoadingStrategies();</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">private static final Map&lt;String, String&gt; <b>specialSPILoadingStrategyMap</b> = getSpecialSPILoadingStrategyMap();</p><p style="margin: 0px 0px 0px 4px;">private static SoftReference&lt;Map&lt;java.net.URL, List&lt;String&gt;&gt;&gt; <b>urlListMapCache</b> =</p><p style="margin: 0px 0px 0px 4px;">&nbsp; &nbsp; &nbsp; &nbsp; new SoftReference&lt;&gt;(new ConcurrentHashMap&lt;&gt;());</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//实例属性注入时需要忽略的方法描述列表(包括ScopeModelAware ExtensionAccessorAware的全部方法),描述和JNI的语法类似,比如 setFrameworkProvider(Lorg/apache/dubbo/common/extension/director/FooFrameworkProvider;)V<br></font></p><p style="margin: 0px 0px 0px 4px;">private static final List&lt;String&gt; <b>ignoredInjectMethodsDesc</b> = getIgnoredInjectMethodsDesc();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//使用SPI时产生的无法接受的异常</font></p><p style="margin: 0px 0px 0px 4px;">private final Set&lt;String&gt; <b>unacceptableExceptions</b> = new ConcurrentHashSet&lt;&gt;();</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//所属的管理器</font></p><p style="margin: 0px 0px 0px 4px;">private final ExtensionDirector <b>extensionDirector</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//指向所属的管理器的拓展后置处理器</font></p><p style="margin: 0px 0px 0px 4px;">private final List&lt;ExtensionPostProcessor&gt; <b>extensionPostProcessors</b>;</p><p style="margin: 0px 0px 0px 4px;"><font color="#007fff">//实例化策略</font></p><p style="margin: 0px 0px 0px 4px;">private InstantiationStrategy <b>instantiationStrategy</b>;</p><p style="margin: 0px 0px 0px 4px;">private final ActivateComparator <b>activateComparator</b>;</p><p style="margin: 0px 0px 0px 4px;">private final ScopeModel <b>scopeModel</b>;</p><p style="margin: 0px 0px 0px 4px;">private final AtomicBoolean destroyed = new AtomicBoolean();</p><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="-1080" y="640" width="560" height="720" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-8" value="<div style="text-align: center; font-size: 9px;"><b style="font-size: 9px;">ExtensionScope (E)</b><br style="font-size: 9px;"></div><hr style="font-size: 9px;"><p style="margin: 0px 0px 0px 4px; font-size: 9px;"><font color="#007fff" style="font-size: 9px;">//表示拓展实例(ExtensionLoader加载的实例)用在framework,所有applications 和 modules 共享</font></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;">FRAMEWORK,<br style="font-size: 9px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;"><font color="#007fff" style="font-size: 9px;">//表示拓展实例用于某个应用,应用下所有modules共享</font></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;">APPLICATION,<br style="font-size: 9px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;"><font color="#007fff" style="font-size: 9px;">//表示拓展实例用于某个模块</font></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;">MODULE,<br style="font-size: 9px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;"><font color="#007fff" style="font-size: 9px;">//用于特殊SPI拓展(没有共享范围层级),如ExtensionInjector</font></p><p style="margin: 0px 0px 0px 4px; font-size: 9px;">SELF</p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=9;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-480" y="320" width="280" height="120" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-9" value="<div style="text-align: center;"><b>ExtensionPostProcessor</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;">依赖属性注入前后处理</p><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><br></p><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-480" y="960" width="440" height="80" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-10" value="<div style="text-align: center;"><b>ExtensionInjector (I)</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;"><b>拓展类属性注入器</b>,类上注释有:@SPI(scope = ExtensionScope.SELF)<br></p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">&lt;T&gt; T getInstance(final Class&lt;T&gt; type, final String name);<br></p><p style="margin: 0px 0px 0px 4px;">default void setExtensionAccessor(final <b>ExtensionAccessor</b> extensionAccessor) {}<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1200" y="320" width="401" height="80" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-11" value="<div style="text-align: center;"><b>LoadingStrategy (I)</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"></p><p style="margin: 0px 0px 0px 4px; font-size: 10px;">加载拓展类的策略</p><p style="margin: 0px 0px 0px 4px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1500" y="640" width="240" height="40" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-12" value="<div style="text-align: center;"><b>InstantiationStrategy</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">实例化策略,用于通过反射实例化类型</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">private final ScopeModelAccessor scopeModelAccessor;<br></p><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">public &lt;T&gt; T instantiate(Class&lt;T&gt; type) throws ReflectiveOperationException;<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1560" y="1080" width="360" height="100" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-13" value="<div style="text-align: center;"><b>ActivateComparator</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">private final List&lt;ExtensionDirector&gt; extensionDirectors;</p><p style="margin: 0px 0px 0px 4px;">private final Map&lt;Class&lt;?&gt;, ActivateInfo&gt; activateInfoMap = new ConcurrentHashMap&lt;&gt;();</p><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"><br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1600" y="940" width="440" height="80" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-14" target="nFbYhWVqmTEnoM216xpz-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-14" value="<div>ExtensionDirector fwExtensionDirector =</div><div>new ExtensionDirector(null, ExtensionScope.FRAMEWORK, FrameworkModel.defaultModel());</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-17" target="nFbYhWVqmTEnoM216xpz-19" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-17" value="<div>ExtensionDirector appExtensionDirector =</div><div>new ExtensionDirector(fwExtensionDirector, ExtensionScope.APPLICATION, ApplicationModel.defaultModel());</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-19" target="nFbYhWVqmTEnoM216xpz-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-19" value="<div style="font-size: 9px;">ExtensionDirector moduleExtensionDirector = new ExtensionDirector(<span style="background-color: initial; font-size: 9px;">appExtensionDirector, ExtensionScope.MODULE,</span></div><div style="font-size: 9px;">ApplicationModel.defaultModel()</div><div style="font-size: 9px;">.getDefaultModule());</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;" parent="1" vertex="1">
<mxGeometry x="280" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-23" target="nFbYhWVqmTEnoM216xpz-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-23" value="<div style="font-size: 9px;">FooFrameworkService testFwSrvFromModule =<span style="background-color: initial; font-size: 9px;">&nbsp;moduleExtensionDirector.getExtension(</span></div><div style="font-size: 9px;"><span style="background-color: initial; font-size: 9px;">FooFrameworkService.class, testFwSrvName);</span></div><div style="font-size: 9px;"><span style="background-color: initial; font-size: 9px;"><font color="#007fff">演示使用MODULE scope的管理器加载&nbsp;</font></span></div><font color="#007fff">FRAMEWORK scope 的类实例</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;" parent="1" vertex="1">
<mxGeometry x="280" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-25" target="nFbYhWVqmTEnoM216xpz-27" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-30" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-25" target="nFbYhWVqmTEnoM216xpz-29" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-25" value="ExtensionLoader&lt;T&gt; extensionLoader = getExtensionLoader(type);<br><font color="#007fff">获取拓展类的类加载器</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="520" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-119" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-27" target="334U5BKtB8SHjy518kIA-118" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-27" value="return extensionLoader != null ? extensionLoader.<b>getExtension</b>(name) : null;<br><font color="#007fff">加载拓展类,并创建拓展类的实例</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="1320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-2" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="nFbYhWVqmTEnoM216xpz-29" target="334U5BKtB8SHjy518kIA-1" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="nFbYhWVqmTEnoM216xpz-29" value="ExtensionLoader&lt;T&gt; loader = (ExtensionLoader&lt;T&gt;) extensionLoadersMap.get(type);<br><font color="#007fff">可能已经创建过加载这个类的ExtensionLoader先从缓存中查</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-22" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-1" target="334U5BKtB8SHjy518kIA-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-1" value="ExtensionScope scope = extensionScopeMap.get(type);<br><font color="#007fff">同样先从缓存中查这个类共享范围</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-3" value="解析类上&nbsp;<b>@SPI&nbsp;</b>注解 scope 字段并缓存" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1000" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-5" target="334U5BKtB8SHjy518kIA-27" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-5" value="loader = createExtensionLoader0(type);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-11" value="Y" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-9" target="334U5BKtB8SHjy518kIA-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-13" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-9" target="334U5BKtB8SHjy518kIA-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-9" value="scope == null" style="rhombus;whiteSpace=wrap;html=1;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="780" y="520" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-14" value="Y" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-12" target="334U5BKtB8SHjy518kIA-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-18" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-12" target="334U5BKtB8SHjy518kIA-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-12" value="loader == null &amp;&amp; scope == ExtensionScope.SELF" style="rhombus;whiteSpace=wrap;html=1;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="780" y="600" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-21" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-15" target="nFbYhWVqmTEnoM216xpz-29" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1310" y="560" as="targetPoint" />
<Array as="points">
<mxPoint x="1220" y="710" />
<mxPoint x="1220" y="430" />
<mxPoint x="740" y="430" />
<mxPoint x="740" y="405" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-15" target="334U5BKtB8SHjy518kIA-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-15" value="loader = this.<b><font style="font-size: 12px;">parent</font></b>.getExtensionLoader(type);<br><font color="#007fff">如果父管理器不为空,通过父管理器获取ExtensionLoader</font>" style="whiteSpace=wrap;html=1;fontSize=10;rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="680" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-19" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-17" target="334U5BKtB8SHjy518kIA-15" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-20" value="Y" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="334U5BKtB8SHjy518kIA-19" vertex="1" connectable="0">
<mxGeometry x="-0.0667" y="-3" relative="1" as="geometry">
<mxPoint y="-3" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-17" value="loader == null" style="rhombus;whiteSpace=wrap;html=1;rounded=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="780" y="680" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-23" target="334U5BKtB8SHjy518kIA-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-23" value="loader = createExtensionLoader(type);<br><font color="#007fff">如果没有父管理器,直接创建</font>" style="whiteSpace=wrap;html=1;fontSize=10;rounded=1;" parent="1" vertex="1">
<mxGeometry x="1000" y="760" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-75" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-25" target="334U5BKtB8SHjy518kIA-27" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1450" y="790" />
<mxPoint x="1450" y="750" />
<mxPoint x="1230" y="750" />
<mxPoint x="1230" y="645" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-25" value="loader = createExtensionLoader0(type);<br><font color="#007fff">需要类型的Scope范围和ExtensionLoader的Scope相同,才会调用createExtensionLoader0() 创建</font>" style="whiteSpace=wrap;html=1;fontSize=10;rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1241" y="760" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-31" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-27" target="334U5BKtB8SHjy518kIA-30" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-87" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-27" target="334U5BKtB8SHjy518kIA-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-27" value="<b>extensionLoadersMap</b>.putIfAbsent(type, <br>new <b>ExtensionLoader</b>&lt;T&gt;(type, this, scopeModel));<br><font color="#007fff">为type类型创建并缓存拓展类加载器</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1241" y="600" width="199" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-30" value="<div>loader = (ExtensionLoader&lt;T&gt;) extensionLoadersMap.get(type);</div><div>return loader;</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1241" y="680" width="199" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-45" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-34" target="334U5BKtB8SHjy518kIA-40" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-34" value="<div style="font-size: 9px;">this.<b>type</b> = type;</div><div style="font-size: 9px;">this.<b>extensionDirector</b> = extensionDirector;</div><div style="font-size: 9px;">this.<b>extensionPostProcessors</b> =&nbsp;</div><div style="font-size: 9px;">extensionDirector.getExtensionPostProcessors();</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;align=left;arcSize=8;" parent="1" vertex="1">
<mxGeometry x="1480" y="600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-38" value="<b>ExtensionLoader</b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1521" y="570" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-39" value="<b>ExtensionDirector</b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="555" y="330" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-40" target="334U5BKtB8SHjy518kIA-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-49" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-40" target="334U5BKtB8SHjy518kIA-48" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-40" value="<div>initInstantiationStrategy();</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1480" y="680" width="199" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-44" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-41" target="334U5BKtB8SHjy518kIA-43" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-66" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-41" target="334U5BKtB8SHjy518kIA-65" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1700" y="790" />
<mxPoint x="1700" y="920" />
<mxPoint x="740" y="920" />
<mxPoint x="740" y="970" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-41" value="<div style="font-size: 9px;">this.<b>injector</b> = (type == ExtensionInjector.class&nbsp;<span style="background-color: initial; font-size: 9px;">? null&nbsp;</span><span style="background-color: initial; font-size: 9px;">: extensionDirector.getExtensionLoader(</span></div><div style="font-size: 9px;"><span style="background-color: initial; font-size: 9px;"><b>ExtensionInjector</b>.class).getAdaptiveExtension());</span></div><div style="font-size: 9px;"><font color="#007fff">加载ExtensionInjector自适应拓展类并实例化</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;align=center;" parent="1" vertex="1">
<mxGeometry x="1480" y="760" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-43" value="<div>this.<b>activateComparator</b> = new ActivateComparator(extensionDirector);</div><div>this.<b>scopeModel</b> = scopeModel;</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1480" y="840" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-48" value="从后置处理器列表中过滤ScopeModelAccessor类型,并用它们创建InstantiationStrategy,返回第一个;<br>没有就直接 new InstantiationStrategy()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1721" y="680" width="199" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-50" value="这里显示获取ExtensionInjector自适应拓展类实例,<br style="font-size: 10px;">自适应拓展类看源码有3种格式:<br style="font-size: 10px;">1 @Adaptive注释的类(这是手动实现的自适应拓展类,通过SPI文件指定加载)<br style="font-size: 10px;">2 classLoader.loadClass(type.getName() + "$Adaptive")<br style="font-size: 10px;">3 使用代码生成器(解析@Adaptive注释的方法)和Dubbo编译器自动生成<br>获取自适应拓展类的流程:<br>1 按LoadingStrategy加载自适应拓展类并缓存<br>2 按InstantiationStrategy实例化并缓存<br><br>比如:<br>META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionInjector 文件下列举了3个实现类<br><div>adaptive=org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector</div><div>spi=org.apache.dubbo.common.extension.inject.SpiExtensionInjector</div><div>scopeBean=org.apache.dubbo.common.beans.ScopeBeanExtensionInjector</div><div><br></div>" style="text;html=1;align=left;verticalAlign=top;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="1721" y="760" width="490" height="190" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-55" value="<ul><li><b>自适应拓展类的原理和作用</b><br>自适应拓展类可以手动实现(类上注解@Adaptive),也可以由Dubbo自动生成,在接口类方法上注解@Adaptive, 通过value属性定义规则,Dubbo会根据规则生成自适应拓展类实现, 类似一个代理类,根据规则选择实现类进行处理。<br>https://cn.dubbo.apache.org/zh-cn/docsv2.7/dev/source/adaptive-extension/</li></ul>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="760" y="10" width="760" height="110" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-60" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;dashed=1;" parent="1" source="334U5BKtB8SHjy518kIA-56" target="nFbYhWVqmTEnoM216xpz-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-56" value="<div style="text-align: center;"><b>DubboExternalLoadingStrategy</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"></p><p style="margin: 0px 0px 0px 4px;">加载 META-INF/dubbo/external/ 下文件列举的拓展类<br></p><p style="margin: 0px 0px 0px 4px;">优先级:MAX_PRIORITY + 1</p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1360" y="720" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-61" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;endArrow=block;endFill=0;dashed=1;" parent="1" source="334U5BKtB8SHjy518kIA-57" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="-1380" y="680" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-57" value="<div style="text-align: center;"><b>DubboInternalLoadingStrategy</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"></p><p style="margin: 0px 0px 0px 4px;">加载 META-INF/dubbo/internal/ 下的拓展类<br></p><p style="margin: 0px 0px 0px 4px;">优先级:MAX_PRIORITY<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1640" y="720" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-64" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;dashed=1;" parent="1" source="334U5BKtB8SHjy518kIA-58" target="nFbYhWVqmTEnoM216xpz-11" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1520" y="810" />
<mxPoint x="-1380" y="810" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-58" value="<div style="text-align: center;"><b>DubboLoadingStrategy</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;">加载&nbsp;META-INF/dubbo/ 下的拓展类</p><p style="margin: 0px 0px 0px 4px;">优先级:NORMAL_PRIORITY<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1640" y="820" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-63" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=block;endFill=0;dashed=1;" parent="1" source="334U5BKtB8SHjy518kIA-59" target="nFbYhWVqmTEnoM216xpz-11" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1240" y="810" />
<mxPoint x="-1380" y="810" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-59" value="<div style="text-align: center;"><b>ServicesLoadingStrategy</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px; font-size: 10px;"></p><p style="margin: 0px 0px 0px 4px;">加载 META-INF/services/ 下的拓展类<br></p><p style="margin: 0px 0px 0px 4px;">优先级:MIN_PRIORITY<br></p><p style="margin: 0px 0px 0px 4px;">这个类是为了加载其他三个LoadingStrategy实现类</p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1360" y="820" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-68" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-65" target="334U5BKtB8SHjy518kIA-67" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-65" value="instance = <b>createAdaptiveExtension</b>();<br>cachedAdaptiveInstance.set(instance);<br><font color="#007fff">&nbsp;先从缓存 cachedAdaptiveInstance 中读取,没有则创建,最后再缓存一下<br>以 ExtensionInjector 为例<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="760" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-70" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-67" target="334U5BKtB8SHjy518kIA-69" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-72" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-67" target="334U5BKtB8SHjy518kIA-71" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-25" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="334U5BKtB8SHjy518kIA-67" target="FCzHFgoopw6_MdKlwMNN-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-67" value="T instance = (T) <b>getAdaptiveExtensionClass</b>()<br>.<b>newInstance</b>();<br><font color="#007fff">先加载<b>自适应拓展类</b>,然后实例化</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1000" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-29" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-69" target="334U5BKtB8SHjy518kIA-146" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1230" y="1240" />
<mxPoint x="1230" y="1655" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-69" value="<div>instance = postProcessBeforeInitialization(</div><div>&nbsp; instance, null);</div><div><b>injectExtension</b>(instance);</div><div>instance = postProcessAfterInitialization(</div><div>&nbsp; instance, null);</div><div><b>initExtension</b>(instance);<font color="#007fff">//lifecycle.initialize();</font></div><div>return instance;</div><div><font color="#007fff">初始化前处理、属性注入、初始化后处理、调用Lifecycle初始化方法</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=5;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="1180" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-71" target="334U5BKtB8SHjy518kIA-88" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-111" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-71" target="334U5BKtB8SHjy518kIA-110" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-71" value="getExtensionClasses();<br><font color="#007fff">加载SPI文件中的拓展类</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1240" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-73" value="<font color="#007fff" style="">上面按 Scope 层级创建了 FRAMEWORK APPLICATION MOUDLE 范围<br style="font-size: 10px;">的三个拓展类加载器的管理器<br>moduleExtensionDirector ---parent---&gt;&nbsp; appExtensionDirector ---parent---&gt;&nbsp; fwExtensionDirector&nbsp;<br></font>" style="text;html=1;align=left;verticalAlign=top;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="490" y="290" width="450" height="50" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-74" value="<font color="#007fff">这一步为拓展类型选择合适的拓展类加载器<br><br>由于类共享范围的不同,应该使用对应共享范围的<br>ExtensionDirector加载、实例化、缓存;<br>这样才能实现上层Scope加载的类、实例可以被下层<br>Scope读取(通过 parent 引用)而下层Scope加载的<br>类、实例不会被上层读取<br><br>如果类scope为空<br>这里的实现就类似JVM类加载器的双亲委派机制,<br>优先使用父ExtensionDirector的ExtensionLoader</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="430" width="250" height="150" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-92" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-88" target="334U5BKtB8SHjy518kIA-91" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-88" value="classes = <b>loadExtensionClasses</b>();<br>cachedClasses.set(classes);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1480" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-94" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-91" target="334U5BKtB8SHjy518kIA-93" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-95" value="..." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="334U5BKtB8SHjy518kIA-94" vertex="1" connectable="0">
<mxGeometry x="-0.3333" y="-3" relative="1" as="geometry">
<mxPoint x="7" y="-3" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-91" value="for strategies:<br><b>loadDirectory</b>(extensionClasses, strategy, type.getName());<br><font color="#007fff">后面逻辑比较清晰,就是遍历加载策略,加载META-INF目录下的<b>type</b>类型</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1720" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-22" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-93" target="FCzHFgoopw6_MdKlwMNN-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-93" value="<div><b>loadClass</b>(classLoader,</div><div>extensionClasses,resourceURL,</div><div>Class.<b>forName</b>(clazz, true, classLoader),</div><div>name, overridden);</div><div><font color="#007fff">name是SPI文件中的key</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1960" y="940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-99" value="<font color="#007fff" style=""><b style="font-size: 10px;">不过类加载后缓存的位置不一定一样:<br style="font-size: 10px;">类上有@Adaptive -&gt;&nbsp;cachedAdaptiveClass<br style="font-size: 10px;">wrapper class -&gt;&nbsp;cachedWrapperClasses, </b>wrapper class 举例: APlus(A a), APlus就是A的 wrapper class<br style="font-size: 10px;"><b style="font-size: 10px;">其他类型 -&gt; cachedClasses、</b><b>cachedActivates、</b></font><font color="#007fff"><b>cachedNames</b></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="2170" y="940" width="490" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-103" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="1" source="334U5BKtB8SHjy518kIA-100" target="nFbYhWVqmTEnoM216xpz-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-107" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="1" source="334U5BKtB8SHjy518kIA-100" target="334U5BKtB8SHjy518kIA-106" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-100" value="<div style="text-align: center;"><b>AdaptiveExtensionInjector</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">这个类其实相当于<b>代理</b>,为实例注入属性时<b>通过此类间接调用其他ExtensionInjector实现</b></span></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;"><font color="#007fff"><br></font></span></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;"><font color="#007fff">//ExtensionInjector实现类实例</font></span><br></p><p style="margin: 0px 0px 0px 4px;">private Collection&lt;ExtensionInjector&gt; <b>injectors</b> = Collections.emptyList();</p><p style="margin: 0px 0px 0px 4px;">private ExtensionAccessor extensionAccessor;</p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-980" y="440" width="400" height="100" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-104" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;dashed=1;endArrow=block;endFill=0;" parent="1" source="334U5BKtB8SHjy518kIA-101" target="334U5BKtB8SHjy518kIA-102" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-105" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="1" source="334U5BKtB8SHjy518kIA-101" target="nFbYhWVqmTEnoM216xpz-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-101" value="<div style="text-align: center;"><b>ScopeBeanExtensionInjector</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">从 ScopeBeanFactory 获取类型实例注入</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">private ScopeBeanFactory beanFactory;<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1580" y="440" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-102" value="<div style="text-align: center;"><b>ScopeModelAware</b><b style="background-color: initial;">&nbsp;(I)</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">default void setScopeModel(ScopeModel scopeModel) {}<br></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">default void setFrameworkModel(FrameworkModel frameworkModel) {}</span><br></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">default void setApplicationModel(ApplicationModel applicationModel) {}<br></span></p><p style="margin: 0px 0px 0px 4px;"><span style="background-color: initial;">default void setModuleModel(ModuleModel moduleModel) {}<br></span></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1560" y="320" width="320" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-106" value="<div style="text-align: center;"><b>Lifecycle</b><b style="background-color: initial;">&nbsp;(I)</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">void initialize() throws IllegalStateException;<br></p><p style="margin: 0px 0px 0px 4px;">void start() throws IllegalStateException;<br></p><p style="margin: 0px 0px 0px 4px;">void destroy() throws IllegalStateException;<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-760" y="320" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-109" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;dashed=1;endArrow=block;endFill=0;entryX=0.396;entryY=1.014;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="334U5BKtB8SHjy518kIA-108" target="nFbYhWVqmTEnoM216xpz-10" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="-1100" y="400" as="targetPoint" />
<Array as="points">
<mxPoint x="-1160" y="430" />
<mxPoint x="-1041" y="430" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-108" value="<div style="text-align: center;"><b>SpiExtensionInjector</b><br></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">通过接口类自适应注入</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">private ExtensionAccessor extensionAccessor;<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-1300" y="440" width="280" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-113" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-110" target="334U5BKtB8SHjy518kIA-112" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-110" value="<div>if (cachedAdaptiveClass != null) {</div><div>return cachedAdaptiveClass;</div><div>}</div><div><font color="#007fff">如果SPI文件有自适应拓展类,直接返回自适应拓展类</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;" parent="1" vertex="1">
<mxGeometry x="1240" y="1020" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-23" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="FCzHFgoopw6_MdKlwMNN-31" target="FCzHFgoopw6_MdKlwMNN-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-112" target="FCzHFgoopw6_MdKlwMNN-31" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-112" value="return cachedAdaptiveClass = <b>createAdaptiveExtensionClass</b>();<br><font color="#007fff">SPI文件中没有自适应拓展类,创建</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1240" y="1100" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-116" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">1 classLoader.loadClass(type.getName() + "$Adaptive"), 之前生成的</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">2 使用代码生成器(解析@Adaptive注释的方法)和Dubbo编译器编译生成</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;编译器有 JdkCompiler JavassistCompiler 两种</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1241" y="1160" width="350" height="50" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-121" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-118" target="334U5BKtB8SHjy518kIA-120" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-123" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-118" target="334U5BKtB8SHjy518kIA-122" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-118" value="<div>String cacheKey = name;</div>final Holder&lt;Object&gt; holder = getOrCreateHolder(cacheKey);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="1320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-125" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-120" target="334U5BKtB8SHjy518kIA-124" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-120" value="Object instance = holder.get();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="1400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-122" value="Holder&lt;Object&gt; holder = <b>cachedInstances</b>.get(name);<div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1000" y="1320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-127" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-124" target="334U5BKtB8SHjy518kIA-126" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-124" value="<div>instance = <b>createExtension</b>(name, wrap);</div><div>holder.set(instance);</div><div>return instance;</div><div><font color="#007fff">类似&nbsp;createAdaptiveExtension()</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="760" y="1480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-129" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-126" target="334U5BKtB8SHjy518kIA-128" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-134" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-126" target="334U5BKtB8SHjy518kIA-88" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1240" y="1510" as="targetPoint" />
<Array as="points">
<mxPoint x="1220" y="1510" />
<mxPoint x="1220" y="1010" />
<mxPoint x="1460" y="1010" />
<mxPoint x="1460" y="985" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-26" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="334U5BKtB8SHjy518kIA-126" target="FCzHFgoopw6_MdKlwMNN-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-126" value="Class&lt;?&gt; clazz = <b>getExtensionClasses</b>().get(name);<br><font color="#007fff">首次获取拓展类实例时,需要先加载拓展类</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1000" y="1480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-138" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-128" target="334U5BKtB8SHjy518kIA-137" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-142" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-128" target="334U5BKtB8SHjy518kIA-143" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1280" y="1620" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-147" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="334U5BKtB8SHjy518kIA-128" target="334U5BKtB8SHjy518kIA-146" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-128" value="&nbsp;extensionInstances.putIfAbsent(clazz, <b>createExtensionInstance</b>(clazz));<br><div>instance = (T)extensionInstances.get(clazz);</div><div><br></div><div>instance = postProcessBeforeInitialization(<br>&nbsp; instance, name);</div><div><b>injectExtension</b>(instance);</div><div>instance = postProcessAfterInitialization(<br>&nbsp; instance, name);</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=5;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="1560" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-130" value="<div style="text-align: center;"><b>SPI</b><b style="background-color: initial;">&nbsp;(@)</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">拓展类标识</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">String value() default "";<br></p><p style="margin: 0px 0px 0px 4px;">ExtensionScope scope() default ExtensionScope.APPLICATION;<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-360" y="200" width="320" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-131" value="<div style="text-align: center;"><b>Adaptive</b><b style="background-color: initial;">&nbsp;(@)</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">拓展类属性注入器标识</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">String[] value() default {};<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-600" y="200" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-132" value="<div style="text-align: center;"><b>Activate</b><b style="background-color: initial;">&nbsp;(@)</b></div><hr style="font-size: 10px;"><p style="margin: 0px 0px 0px 4px;">拓展类自动激活条件注解</p><p style="margin: 0px 0px 0px 4px;"><br></p><p style="margin: 0px 0px 0px 4px;">String[] group() default {};<br></p><p style="margin: 0px 0px 0px 4px;">String[] value() default {};<br></p><p style="margin: 0px 0px 0px 4px;">int order() default 0;<br></p><p style="margin: 0px 0px 0px 4px;">String[] onClass() default {};<br></p>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;whiteSpace=wrap;" parent="1" vertex="1">
<mxGeometry x="-840" y="200" width="200" height="100" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-140" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-137" target="334U5BKtB8SHjy518kIA-139" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-137" value="wrapperClass处理<br><font color="#007fff">官方称<b>AOP生成包装类</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1000" y="1880" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-139" value="<div>initExtension(instance);</div><div>return instance;</div><div><font color="#007fff">执行生命周期接口 initialize()&nbsp;</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="1960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-145" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-143" target="334U5BKtB8SHjy518kIA-144" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-143" value="createExtensionInstance(clazz)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1241" y="1560" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-144" value="return <b>instantiationStrategy</b>.instantiate(type);<br><font color="#007fff">反射实例化</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1479" y="1560" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-149" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-146" target="334U5BKtB8SHjy518kIA-148" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-146" value="<div>injectExtension(instance)</div><div><font color="#007fff">为实例注入属性,就是通过AdaptiveExtensionInjector</font></div><div><font color="#007fff">官方称<b>IOC依赖属性注入</b></font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1241" y="1640" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="334U5BKtB8SHjy518kIA-148" target="FCzHFgoopw6_MdKlwMNN-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="334U5BKtB8SHjy518kIA-148" value="遍历instance类型所有public方法<br>然后筛选<b>没有@DisableInject注释、非ScopeModelAware、ExtensionAccessorAware</b><br><b>声明、方法参数非基本类型</b>的<b>Setter</b>方法" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1481" y="1640" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-6" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="FCzHFgoopw6_MdKlwMNN-3" target="FCzHFgoopw6_MdKlwMNN-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-8" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="FCzHFgoopw6_MdKlwMNN-3" target="FCzHFgoopw6_MdKlwMNN-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-3" value="String property = getSetterProperty(method);<br>Object object = <b>injector</b>.<b>getInstance</b>(pt, property);<br><font color="#007fff">获取要注入的属性实例</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1481" y="1720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-5" value="<div>if (object != null) {</div><div>method.<b>invoke</b>(instance, object);</div><div>}</div><div><font color="#007fff">反射调用setter方法实现注入</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1481" y="1800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="FCzHFgoopw6_MdKlwMNN-7" target="FCzHFgoopw6_MdKlwMNN-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-16" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="FCzHFgoopw6_MdKlwMNN-7" target="FCzHFgoopw6_MdKlwMNN-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-7" value="<div>return injectors.stream()</div><div>.map(injector -&gt; injector.<b>getInstance</b>(type, name))</div><div>.filter(Objects::nonNull)</div><div>.findFirst()</div><div>.orElse(null);</div><font color="#007fff">遍历ExtensionInjector实例,获取实例,返回第一个,所以说AdaptiveExtensionInjector像是个代理</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=5;" parent="1" vertex="1">
<mxGeometry x="1720" y="1690" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-9" value="AdaptiveExtensionInjector" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1740" y="1660" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="FCzHFgoopw6_MdKlwMNN-10" target="FCzHFgoopw6_MdKlwMNN-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-10" value="<b>ScopeBeanExtensionInjector</b>#getInstance(<br>final Class&lt;T&gt; type, final String name)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=15;" parent="1" vertex="1">
<mxGeometry x="1960" y="1720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="FCzHFgoopw6_MdKlwMNN-12" target="FCzHFgoopw6_MdKlwMNN-17" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-12" value="<b>SpiExtensionInjector</b>#getInstance(<br>final Class&lt;T&gt; type, final String name)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=15;" parent="1" vertex="1">
<mxGeometry x="1960" y="1800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-14" value="return beanFactory == null ? null : <b>beanFactory</b>.<b>getBean</b>(name, type);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;arcSize=15;" parent="1" vertex="1">
<mxGeometry x="2200" y="1720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-19" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" parent="1" source="FCzHFgoopw6_MdKlwMNN-17" target="nFbYhWVqmTEnoM216xpz-25" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2420" y="1880" />
<mxPoint x="2420" y="350" />
<mxPoint x="500" y="350" />
<mxPoint x="500" y="375" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-27" style="rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" source="FCzHFgoopw6_MdKlwMNN-17" target="FCzHFgoopw6_MdKlwMNN-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-17" value="<div style="font-size: 9px;">if (!type.<b style="font-size: 9px;">isInterface</b>()&nbsp;</div><div style="font-size: 9px;">&nbsp; &nbsp; || !type.isAnnotationPresent(<b style="font-size: 9px;">SPI</b>.class)) {</div><div style="font-size: 9px;">&nbsp; &nbsp; return null;</div><div style="font-size: 9px;">}</div><div style="font-size: 9px;">ExtensionLoader&lt;T&gt; loader = <b style="font-size: 9px;">extensionAccessor</b>.<b style="font-size: 9px;">getExtensionLoader</b>(type);</div><div style="font-size: 9px;">if (loader == null) {</div><div style="font-size: 9px;">&nbsp; &nbsp; return null;</div><div style="font-size: 9px;">}</div><div style="font-size: 9px;">if (!loader.getSupportedExtensions().isEmpty()) {</div><div style="font-size: 9px;">&nbsp; &nbsp; return loader.<b style="font-size: 9px;">getAdaptiveExtension</b>();</div><div style="font-size: 9px;">}</div><div style="font-size: 9px;">return null;</div><div style=""><font color="#007fff">extensionAccessor是ExtensionDirector实例</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;align=left;arcSize=4;" parent="1" vertex="1">
<mxGeometry x="2200" y="1800" width="200" height="160" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-21" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><b style="font-size: 10px;">还以为Dubbo SPI是通过封装JDK ServiceLoader 实现的,</b></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><b style="font-size: 10px;">实际并不是,如果SPI文件中有明确给定类名代码中有提供实现就用 Class.forName加载,</b></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><b style="font-size: 10px;">否则通过代码生成器和编译器生成并加载,</b></font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;"><b style="font-size: 10px;">Dubbo SPI ExtensionLoader 也有使用 ServiceLoader 不过只是用于加载 LoadingStrategy 实现</b></font></div>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1860" y="1030" width="540" height="50" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-24" value="<div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><b style="font-size: 10px;">对比加载自适应拓展类多了一个判断:</b></font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><b style="font-size: 10px;">如果SPI文件中没有指定自适应拓展类,就通过</b></font></div><font style="" color="#007fff"><b style="font-size: 10px;">createAdaptiveExtensionClass()创建</b><br><b style="font-size: 10px;">某接口类的自适应拓展类有且只能有一个</b><br><br><div style=""><b>if (!loader.getSupportedExtensions().isEmpty()) {</b></div><div style=""><b>&nbsp; &nbsp; return loader.getAdaptiveExtension();</b></div><div style=""><b>}</b></div><b>如果接口类型实现(cachedClasses)不为空就创建自适应拓展类实例</b><br></font>" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1280" y="1320" width="320" height="120" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-28" value="<div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">生成的一个自适应拓展类,经过了格式化:</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><br></font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">public class FooFrameworkProvider<b>$Adaptive</b> implements FooFrameworkProvider {</font></div><div style="font-size: 10px;"><b><font color="#007fff">&nbsp; &nbsp; //被重写的 @Adaptive 修饰的接口方法</font></b></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; public void <b>process</b>(org.apache.dubbo.common.URL arg0) {</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; if (arg0 == null)</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalArgumentException("url == null");</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; URL url = arg0;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; String extName = url.getParameter("foo.framework.provider");</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; if (extName == null)</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalStateException("...");</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><br style="font-size: 10px;"></font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), FooFrameworkProvider.class);</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; FooFrameworkProvider extension = (FooFrameworkProvider) scopeModel.getExtensionLoader(FooFrameworkProvider.class)</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getExtension(extName);</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; extension.process(arg0);</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; &nbsp; }</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">}</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1800" y="1095" width="600" height="230" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-30" value="<font color="#ea6b66" style="font-size: 10px;">这个单元测试中获取的拓展类实例内部字段属性注入都失败(全为null),最终原因是没有配置ScopeBeanFactory,导致<br style="font-size: 10px;">AdaptiveCompiler属性为空,编译生成的代码时会报空指针异常<br style="font-size: 10px;"></font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="1200" width="220" height="80" as="geometry" />
</mxCell>
<mxCell id="FCzHFgoopw6_MdKlwMNN-31" value="<div style="font-size: 9px;"><font style="font-size: 9px;">String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">org.apache.dubbo.common.compiler.Compiler compiler = extensionDirector</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; .getExtensionLoader(org.apache.dubbo.common.compiler.<b>Compiler</b>.class)</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; .getAdaptiveExtension();</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">return compiler.<b>compile</b>(type, code, classLoader);</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=9;align=left;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1480" y="1095" width="319" height="70" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-3" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-1" target="BtQ9-s-YfgyTIdZ3fDr7-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-1" value="<b>AdaptiveClassCodeGenerator</b><br>自适应类生成原理" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="40" y="2040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-2" target="BtQ9-s-YfgyTIdZ3fDr7-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-2" value="AdaptiveClassCodeGenerator generator = new AdaptiveClassCodeGenerator(<br>ProxyFactory.class, "proxyFactory");" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="2040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-7" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-4" target="BtQ9-s-YfgyTIdZ3fDr7-6" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-8" value="..." style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="BtQ9-s-YfgyTIdZ3fDr7-7" vertex="1" connectable="0">
<mxGeometry x="-0.1" y="3" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-4" value="String value = generator.generate();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="2120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-6" target="BtQ9-s-YfgyTIdZ3fDr7-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-6" value="&nbsp;String methodContent = generateMethodContent(method);<br><font color="#007fff">其他部分代码比较固定,主要是方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="520" y="2120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-9" value="<font color="#007fff">没找到官方文档哪里有讲自适应方法参数定义规则<br>本来以为方法第一个参数需要是<br>org.apache.dubbo.common.URL,<br>但看其他源码发现并不是这样,甚至顺序也不需要是第一个<br>感觉很困惑,所以看下源码,看看方法参数到底怎么定义<br><br>结论:<b>自适应方法参数列表中要么包含URL参数,要么有参数包含能返回URL的方法<br></b><br><div>另外需要关注两个重要语句生成原理:</div><div>1 获取Url对象代码的生成逻辑</div><div>2 获取最终引用的拓展类名代码的生成逻辑</div><div><br></div><div>比如:org.apache.dubbo.rpc.Protocol 的自适应拓展类export方法的下面两行代码</div><div>org.apache.dubbo.common.URL url = arg0.getUrl();</div><div>String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );</div><div><br></div><div><br></div><div><div>@SPI(value = "dubbo", scope = ExtensionScope.FRAMEWORK)</div><div>public interface Protocol {</div></div><div><br></div><div><div>&nbsp; &nbsp; @Adaptive</div><div>&nbsp; &nbsp; &lt;T&gt; Exporter&lt;T&gt; export(Invoker&lt;T&gt; invoker) throws RpcException;</div></div><div>}</div></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="2140" width="390" height="290" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-13" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-10" target="BtQ9-s-YfgyTIdZ3fDr7-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-10" value="Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="2120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-12" target="BtQ9-s-YfgyTIdZ3fDr7-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-12" value="int urlTypeIndex = getUrlTypeIndex(method);<br><font color="#007fff">获取URL类型参数的索引</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="2200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-17" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-14" target="BtQ9-s-YfgyTIdZ3fDr7-16" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-18" value="Y" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="BtQ9-s-YfgyTIdZ3fDr7-17" vertex="1" connectable="0">
<mxGeometry x="-0.04" y="-4" relative="1" as="geometry">
<mxPoint x="6" y="-22" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-20" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-14" target="BtQ9-s-YfgyTIdZ3fDr7-19" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-21" value="N" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="BtQ9-s-YfgyTIdZ3fDr7-20" vertex="1" connectable="0">
<mxGeometry x="0.625" relative="1" as="geometry">
<mxPoint x="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-14" target="34Wvdx35s0JXqbyZLGz6-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-14" value="urlTypeIndex <br>!= -1" style="rhombus;whiteSpace=wrap;html=1;fontSize=10;rounded=1;" parent="1" vertex="1">
<mxGeometry x="800" y="2320" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-40" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-16" target="BtQ9-s-YfgyTIdZ3fDr7-39" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-16" value="code.append(<br>generateUrlNullCheck(urlTypeIndex));<br><font color="#007fff">即参数列表中包含URL类型参数</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1000" y="2280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-23" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-19" target="BtQ9-s-YfgyTIdZ3fDr7-22" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-19" value="code.append(<br>generateUrlAssignmentIndirectly(method));<br><font color="#007fff">即参数列表中不包含URL类型参数,那就遍历参数列表寻找返回URL的方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1000" y="2360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-25" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-22" target="BtQ9-s-YfgyTIdZ3fDr7-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-22" value="Class&lt;?&gt;[] pts = method.getParameterTypes();<br>获取参数类型列表" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1240" y="2360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-24" target="BtQ9-s-YfgyTIdZ3fDr7-26" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-24" value="遍历所有参数的所有方法<br>找到所有返回 URL 类型且 public 非static<br>(以get开头 || 方法名长度大于3)的方法<br><font color="#007fff">如果没有满足要求的方法就直接抛异常</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1240" y="2440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-35" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-26" target="BtQ9-s-YfgyTIdZ3fDr7-32" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-26" value="Integer index = getterReturnUrl.get("getUrl");<br><font color="#007fff">先查上一步中有没有名为 getUrl的方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1240" y="2520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-28" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-32" target="BtQ9-s-YfgyTIdZ3fDr7-33" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-29" value="Y" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="BtQ9-s-YfgyTIdZ3fDr7-28" vertex="1" connectable="0">
<mxGeometry x="-0.04" y="-4" relative="1" as="geometry">
<mxPoint x="6" y="-22" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-30" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-32" target="BtQ9-s-YfgyTIdZ3fDr7-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-31" value="N" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="BtQ9-s-YfgyTIdZ3fDr7-30" vertex="1" connectable="0">
<mxGeometry x="0.625" relative="1" as="geometry">
<mxPoint x="-8" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-32" value="index != null" style="rhombus;whiteSpace=wrap;html=1;fontSize=10;rounded=1;" parent="1" vertex="1">
<mxGeometry x="1280" y="2640" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-33" target="BtQ9-s-YfgyTIdZ3fDr7-36" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-33" value="return <b>generateGetUrlNullCheck</b>(index, pts[index], "getUrl");<br><font color="#007fff">即有getUrl方法</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1481" y="2600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-38" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" parent="1" source="BtQ9-s-YfgyTIdZ3fDr7-34" target="BtQ9-s-YfgyTIdZ3fDr7-33" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1701" y="2720" />
<mxPoint x="1701" y="2670" />
<mxPoint x="1461" y="2670" />
<mxPoint x="1461" y="2645" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-34" value="<div>Map.Entry&lt;String, Integer&gt; entry =<span style="background-color: initial;">&nbsp; getterReturnUrl.entrySet().iterator().next();</span></div><div>return <b>generateGetUrlNullCheck</b>(</div><div>entry.getValue(), pts[entry.getValue()], entry.getKey());</div><div><font color="#007fff">没有getUrl方法,就默认使用第一个返回URL的方法</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1481" y="2680" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-36" value="...<br>code.append(String.format("%s url = arg%d.%s();\n", URL.class.getName(), index, method));<br>..." style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1720" y="2600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-39" value="return String.format(CODE_URL_NULL_CHECK, index, URL.class.getName(), index);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1241" y="2280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="BtQ9-s-YfgyTIdZ3fDr7-41" value=""if (arg%d == null) throw new IllegalArgumentException(\"url == null\");\n<br>%s <b>url = arg%d</b>;\n";" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1450" y="2290" width="410" height="40" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-6" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="34Wvdx35s0JXqbyZLGz6-1" target="34Wvdx35s0JXqbyZLGz6-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-1" value="&nbsp;String[] value = getMethodAdaptiveValue(<br>adaptiveAnnotation);<br><font color="#007fff">获取@Adaptive value数组,数组为空就获取接口类名(CAMEL转全小写,英文句号分割)<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="760" y="2440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-4" value="<font color="#007fff">以org.apache.dubbo.rpc.Protocol export()为例<br>这一步获取的是 ["protocol"]</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="490" y="2450" width="270" height="40" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-8" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="34Wvdx35s0JXqbyZLGz6-5" target="34Wvdx35s0JXqbyZLGz6-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-5" value="boolean hasInvocation = hasInvocationArgument(method);<br><font color="#007fff">是否有Invocation类型参数<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="760" y="2520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-10" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="34Wvdx35s0JXqbyZLGz6-7" target="34Wvdx35s0JXqbyZLGz6-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-7" value="code.append(<br>generateInvocationArgumentNullCheck(<br>method));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="760" y="2600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-13" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="34Wvdx35s0JXqbyZLGz6-9" target="34Wvdx35s0JXqbyZLGz6-12">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-16" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="34Wvdx35s0JXqbyZLGz6-9" target="34Wvdx35s0JXqbyZLGz6-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-9" value="code.append(<br><b>generateExtNameAssignment</b>(<br>value, hasInvocation));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="760" y="2680" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-11" value="<font color="#007fff">以org.apache.dubbo.rpc.Protocol export()为例<br>这一步生成的是<br>String extName = ( url.getProtocol() == null ? <br>"dubbo" : url.getProtocol() );<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="490" y="2675" width="270" height="70" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-12" value="直接去看代码吧,不太方便描述<br>代码倒是比较简单" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1000" y="2680" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-14" value="<font color="#007fff">以org.apache.dubbo.rpc.Protocol export()为例<br>这一步生成的是<br><div>org.apache.dubbo.common.URL url = arg0.getUrl();</div></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1920" y="2600" width="300" height="60" as="geometry" />
</mxCell>
<mxCell id="34Wvdx35s0JXqbyZLGz6-15" value="其他不太重要" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="760" y="2760" width="200" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>