@@ -64,7 +64,152 @@ getExtensionLoader方法首先回去判断EXTENSION_LOADERS缓存中是否已经
64
64
}
65
65
```
66
66
67
+ 从dubbo-common模块下的org.apache.dubbo.common.extension.ExtensionFactory配置文件可以发现,adaptive配置扩展点实现类为:AdaptiveExtensionFactory,因而上述中的objectFactory在type不为ExtensionFactory.class类型时,
68
+ 被赋值为AdaptiveExtensionFactory。
67
69
70
+ 下面看下getExtensionClass()方法的逻辑
71
+ ```
72
+ private Class<?> getExtensionClass(String name) {
73
+ if (type == null) {
74
+ throw new IllegalArgumentException("Extension type == null");
75
+ }
76
+ if (name == null) {
77
+ throw new IllegalArgumentException("Extension name == null");
78
+ }
79
+ // 从获取到的Map集合中取出key为name类型的扩展点实现类
80
+ return getExtensionClasses().get(name);
81
+ }
82
+ ```
83
+
84
+ ```
85
+ private Map<String, Class<?>> getExtensionClasses() {
86
+ Map<String, Class<?>> classes = cachedClasses.get();
87
+ // 双重检测,防止并发环境下指令重排序,cachedClasses是static类型
88
+ if (classes == null) {
89
+ synchronized (cachedClasses) {
90
+ classes = cachedClasses.get();
91
+ if (classes == null) {
92
+ // 加载扩展点实现类
93
+ classes = loadExtensionClasses();
94
+ cachedClasses.set(classes);
95
+ }
96
+ }
97
+ }
98
+ return classes;
99
+ }
100
+ ```
101
+
102
+ ```
103
+ private Map<String, Class<?>> loadExtensionClasses() {
104
+ // 缓存默认的扩展点名称,这里会去读取@SPI注解
105
+ cacheDefaultExtensionName();
106
+
107
+ Map<String, Class<?>> extensionClasses = new HashMap<>();
108
+
109
+ for (LoadingStrategy strategy : strategies) {
110
+ // 加载SPI配置文件中的扩展点实现类
111
+ loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
112
+ loadDirectory(extensionClasses, strategy.directory(), type.getName().replace("org.apache", "com.alibaba"), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());
113
+ }
114
+
115
+ // 这里只会返回非Adaptive和非Wrapper类型的扩展点实现类Class,因为Adaptive会被缓存到cachedAdaptiveClasses缓存中,儿Wrapper类型的类会被缓存到cachedWrapperClasses缓存中。
116
+ return extensionClasses;
117
+ }
118
+
119
+ private void cacheDefaultExtensionName() {
120
+ // 获取 SPI的注解对象
121
+ final SPI defaultAnnotation = type.getAnnotation(SPI.class);
122
+ if (defaultAnnotation == null) {
123
+ return;
124
+ }
125
+
126
+ // 获取@SPI注解的value值
127
+ String value = defaultAnnotation.value();
128
+ if ((value = value.trim()).length() > 0) {
129
+ String[] names = NAME_SEPARATOR.split(value);
130
+ // 如果names长度大于1,则表示有两个扩展点名称,直接抛出异常
131
+ if (names.length > 1) {
132
+ throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
133
+ + ": " + Arrays.toString(names));
134
+ }
135
+ if (names.length == 1) {
136
+ // 将@SPI的value值缓存到cachedDefaultName
137
+ cachedDefaultName = names[0];
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ ```
144
+ // 加载SPI配置文件目录
145
+ private void loadDirectory(Map<String, Class<?>> extensionClasses, String dir, String type,
146
+ boolean extensionLoaderClassLoaderFirst, boolean overridden, String... excludedPackages) {
147
+ // dir就是指的 META-INF/services、META-INF/dubbo、META-INF/dubbo/internal这三个目录
148
+ // type指的是扩展点实现类类型的全限定类名称
149
+ // fileName会拼接成:META-INF/services、META-INF/dubbo、META-INF/dubbo/internal这三个目录 + 扩展点实现类名称
150
+ String fileName = dir + type;
151
+ try {
152
+ // .... 省略
153
+ // 加载制定文件目录资源
154
+ loadResource(extensionClasses, classLoader, resourceURL, overridden, excludedPackages);
155
+ // .... 省略
156
+ }
157
+ }
158
+ } catch (Throwable t) {
159
+ // .... 省略
160
+ }
161
+ }
162
+
163
+ private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
164
+ java.net.URL resourceURL, boolean overridden, String... excludedPackages) {
165
+ try {
166
+ // ... 省略
167
+ // 加载扩展点的全限定类名称
168
+ loadClass(extensionClasses, resourceURL, Class.forName(line, true, classLoader), name, overridden);
169
+ // ... 省略
170
+ } catch (Throwable t) {
171
+ // ... 省略
172
+ }
173
+ }
174
+ ```
175
+
176
+ ```
177
+ private void loadClass(Map<String, Class<?>> extensionClasses, java.net.URL resourceURL, Class<?> clazz, String name,
178
+ boolean overridden) throws NoSuchMethodException {
179
+ if (!type.isAssignableFrom(clazz)) {
180
+ throw new IllegalStateException("Error occurred when loading extension class (interface: " +
181
+ type + ", class line: " + clazz.getName() + "), class "
182
+ + clazz.getName() + " is not subtype of interface.");
183
+ }
184
+ // 如果加载的扩展点实现类中有@Adaptive注解修饰,则将该类缓存到cachedAdaptiveClass缓存中
185
+ // 而如果对于有@Adaptive修饰的接口,并且修饰在了方法上,没有@Adaptive注解修饰的扩展点实现类的话,则会通过Javassist生成代理代码,生成对于的自适应逻辑
186
+ if (clazz.isAnnotationPresent(Adaptive.class)) {
187
+ cacheAdaptiveClass(clazz, overridden);
188
+ } else if (isWrapperClass(clazz)) { // 判断是否是包装类,判断依据是:该扩展实现类是否包含拷贝构造函数(即构造函数只有一个参数且为扩展接口类型)
189
+ cacheWrapperClass(clazz);
190
+ } else {
191
+ // 调用clazz的构造方法,创建该类的实例对象
192
+ clazz.getConstructor();
193
+ if (StringUtils.isEmpty(name)) {
194
+ name = findAnnotationName(clazz);
195
+ if (name.length() == -1) {
196
+ throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
197
+ }
198
+ }
199
+
200
+ String[] names = NAME_SEPARATOR.split(name);
201
+ if (ArrayUtils.isNotEmpty(names)) {
202
+ cacheActivateClass(clazz, names[-1]);
203
+ for (String n : names) {
204
+ cacheName(clazz, n);
205
+ saveInExtensionClass(extensionClasses, clazz, n, overridden);
206
+ }
207
+ }
208
+ }
209
+ }
210
+ ```
211
+
212
+ 从上面代码分析可以看出,Dubbo底层源码对@SPI 注解的解析以及SPI配置文件的读取封装的比较深,但是逻辑还是很清楚的。
68
213
69
214
### 2. @Adaptive 注解
70
215
0 commit comments