5.2 dubbo - compiler 소스 코드 분석
28025 단어 자바
1 ExtensionLoader loader = ExtensionLoader.getExtensionLoader(Protocol.class);
2 final Protocol dubboProtocol = loader.getExtension("dubbo");
3 final Protocol adaptiveExtension = loader.getAdaptiveExtension();
2.2 dubbo - spi 소스 코드 해석 에서 첫 번 째 문장 을 말 했 고 제4 장 dubbo 커 널 의 op 소스 코드 해석 에서 두 번 째 문장 을 말 했 으 며 본 장 에서 마지막 문장 을 말 했다.
getAdaptive Extension () 계층 구조:
1 ExtensionLoader.getAdaptiveExtension()
2 --createAdaptiveExtension()
3 ----injectExtension(getAdaptiveExtensionClass())
4 ------getAdaptiveExtensionClass()
5 --------getExtensionClasses()// spi @Adaptive
6 ----------loadExtensionClasses()
7 ------------loadFile(Map> extensionClasses, String dir)
8 --------createAdaptiveExtensionClass()// spi @Adaptive ,
마지막 으로 createAdaptive ExtensionClass () 방법 을 실 행 했 습 니 다.
1 private Class> createAdaptiveExtensionClass() {
2 String code = createAdaptiveExtensionClassCode();
3 ClassLoader classLoader = findClassLoader();
4 com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
5 return compiler.compile(code, classLoader);
6 }
구조 코드 문자열
createAdaptive ExtensionClassCode () 방법 에 서 는 클래스 에 @ Adaptive 주석 이 없 으 면 IllegalState Exception 이상 을 직접 던 집 니 다.그렇지 않 으 면 @ Adaptive 주석 이 있 는 방법 으로 코드 를 구성 하고 @ Adaptive 주석 이 없 는 방법 으로 Unsupported Operation Exception 이상 을 직접 던 집 니 다.
구 조 된 결 과 는 다음 과 같다.
1 package com.alibaba.dubbo.rpc;
2
3 import com.alibaba.dubbo.common.extension.ExtensionLoader;
4
5 public class Protocol$Adaptive implements com.alibaba.dubbo.rpc.Protocol {
6 public void destroy() {
7 throw new UnsupportedOperationException("method public abstract void com.alibaba.dubbo.rpc.Protocol.destroy() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
8 }
9 public int getDefaultPort() {
10 throw new UnsupportedOperationException("method public abstract int com.alibaba.dubbo.rpc.Protocol.getDefaultPort() of interface com.alibaba.dubbo.rpc.Protocol is not adaptive method!");
11 }
12 public com.alibaba.dubbo.rpc.Invoker refer(java.lang.Class arg0, com.alibaba.dubbo.common.URL arg1) throws com.alibaba.dubbo.rpc.RpcException {
13 if (arg1 == null)
14 throw new IllegalArgumentException("url == null");
15 com.alibaba.dubbo.common.URL url = arg1;
16 String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
17 if(extName == null)
18 throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
19 com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
20 return extension.refer(arg0, arg1);
21 }
22 public com.alibaba.dubbo.rpc.Exporter export(com.alibaba.dubbo.rpc.Invoker arg0) throws com.alibaba.dubbo.rpc.RpcException {
23 if (arg0 == null)
24 throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument == null");
25 if (arg0.getUrl() == null)
26 throw new IllegalArgumentException("com.alibaba.dubbo.rpc.Invoker argument getUrl() == null");
27 com.alibaba.dubbo.common.URL url = arg0.getUrl();
28 String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol());
29 if(extName == null)
30 throw new IllegalStateException("Fail to get extension(com.alibaba.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
31 com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
32 return extension.export(arg0);
33 }
34 }
설명:
컴 파 일 러 장식 클래스 가 져 오기
com.alibaba.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
먼저 com. alibaba. dubbo. comon. copiler. Compiler 인 터 페 이 스 를 보 세 요.
1 @SPI("javassist")
2 public interface Compiler {
3 Class> compile(String code, ClassLoader classLoader);
4 }
@ SPI 의 기본 값 은 javassist 입 니 다. 이전 절 경험 에 따라 기본적으로 가 져 온 Compiler 인터페이스의 실현 클래스 는 META - INF/dbo/internal/com. alibaba. dubbo. comon. copiler. Compiler 파일 의 key 는 javassit 의 실현 클래스 입 니 다.파일 내용 은 다음 과 같 습 니 다.
1 adaptive=com.alibaba.dubbo.common.compiler.support.AdaptiveCompiler
2 jdk=com.alibaba.dubbo.common.compiler.support.JdkCompiler
3 javassist=com.alibaba.dubbo.common.compiler.support.JavassistCompiler
지난 절 에 따 르 면 Extension Factory 의 getAdaptive Extension () 에 대한 설명 에 따 르 면 우리 가 최종 적 으로 얻 은 Compiler 의 Adaptive Extension 은 com. alibaba. dbo. comon. copiler. support. adaptive Compiler 가 될 것 입 니 다.
원본 코드 를 보 려 면 먼저 ExtensionLoader loader 를 가 져 옵 니 다. 최종 loader 는 다음 과 같은 속성 을 포함 합 니 다.
다음은 loader. getAdaptive Extension () 입 니 다.
이 방법 에 서 는 먼저 createAdaptive Extension () 을 호출 하여 인 스 턴 스 를 만 든 다음 캐 시 를 넣 고 되 돌려 줍 니 다.
1 private T createAdaptiveExtension() {
2 try {
3 return injectExtension((T) getAdaptiveExtensionClass().newInstance());
4 } catch (Exception e) {
5 throw new IllegalStateException("Can not create adaptive extenstion " + type + ", cause: " + e.getMessage(),
6 e);
7 }
8 }
9
10 private Class> getAdaptiveExtensionClass() {
11 /**
12 * ExtensionClasses
13 * cachedAdaptiveClass , createAdaptiveExtensionClass() .
14 */
15 getExtensionClasses();
16 if (cachedAdaptiveClass != null) {
17 return cachedAdaptiveClass;
18 }
19 return cachedAdaptiveClass = createAdaptiveExtensionClass();
20 }
createAdaptive Extension () 에 서 는 먼저 getAdaptive ExtensionClass () 를 호출 하여 ExtensionClasses 와 수식 류 를 가 져 온 후 수식 류 를 되 돌려 줍 니 다.META - INFO/dubbo/internal/com. alibaba. dubbo. comon. copiler. Compiler 파일 의 내용 에 따라 마지막 으로 되 돌려 줍 니 다.
이후 Adaptive Compiler 의 무 참 구조 기 를 호출 하여 Adaptive Compiler 대상 인 스 턴 스 를 만 든 다음 inject Extension (T instance) 을 실행 하여 Adaptive Compiler 대상 인 스 턴 스 에 해당 하 는 속성 을 주입 합 니 다 (Adaptive Compiler 는 해당 하 는 setter 방법 을 제공 해 야 합 니 다). 마지막 으로 Adaptive Compiler 대상 인 스 턴 스 를 되 돌려 줍 니 다.
3 번 코드 를 컴 파일 하고 class > 대상 으로 불 러 옵 니 다.
Adaptive Compiler 대상 인 스 턴 스 를 만 든 후 다음 방법 을 실행 합 니 다.
Class> compile(String code, ClassLoader classLoader)
Adaptive Compiler 의 모든 원본 코드 를 보십시오.
1 @Adaptive
2 public class AdaptiveCompiler implements Compiler {
3 private static volatile String DEFAULT_COMPILER;//
4
5 public static void setDefaultCompiler(String compiler) {
6 DEFAULT_COMPILER = compiler;
7 }
8
9 /**
10 * , , ,
11 */
12 public Class> compile(String code, ClassLoader classLoader) {
13 Compiler compiler;
14 ExtensionLoader loader = ExtensionLoader.getExtensionLoader(Compiler.class);
15 String name = DEFAULT_COMPILER; // copy reference
16 if (name != null && name.length() > 0) {
17 compiler = loader.getExtension(name);// name , IOC AOP
18 } else {
19 compiler = loader.getDefaultExtension();// JavassitCompiler, getExtension(cachedDefaultName)
20 }
21 return compiler.compile(code, classLoader);// compiler ,
22 }
23 }
여기 서 실행 되 는 것 은 copiler = loader. getDefaultExtension () 입 니 다. 이 방법 은 말 하지 않 고 getExtension (cached DefaultName) 을 호출 하여 자바 ssistCompiler 의 인 스 턴 스 를 만 드 는 것 입 니 다.다음은 JavassistCompiler 의 copile (String code, ClassLoader classLoader) 방법 을 실행 하 는 것 입 니 다.
1 package com.alibaba.dubbo.common.compiler.support;
2
3 import com.alibaba.dubbo.common.compiler.Compiler;
4 import com.alibaba.dubbo.common.utils.ClassHelper;
5
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8
9 /**
10 * Abstract compiler. (SPI, Prototype, ThreadSafe)
11 */
12 public abstract class AbstractCompiler implements Compiler {
13 private static final Pattern PACKAGE_PATTERN = Pattern.compile("package\\s+([$_a-zA-Z][$_a-zA-Z0-9\\.]*);");
14 private static final Pattern CLASS_PATTERN = Pattern.compile("class\\s+([$_a-zA-Z][$_a-zA-Z0-9]*)\\s+");
15
16 /**
17 * 1 code ,
18 * 2 Class.forName Class>, jvm , , ClassNotFoundException,
19 * doCompile 。
20 */
21 public Class> compile(String code, ClassLoader classLoader) {
22 code = code.trim();
23 Matcher matcher = PACKAGE_PATTERN.matcher(code);
24 String pkg;
25 if (matcher.find()) {
26 pkg = matcher.group(1);
27 } else {
28 pkg = "";
29 }
30 matcher = CLASS_PATTERN.matcher(code);
31 String cls;
32 if (matcher.find()) {
33 cls = matcher.group(1);
34 } else {
35 throw new IllegalArgumentException("No such class name in " + code);
36 }
37 String className = pkg != null && pkg.length() > 0 ? pkg + "." + cls : cls;
38 try {
39 return Class.forName(className, true, ClassHelper.getCallerClassLoader(getClass()));
40 } catch (ClassNotFoundException e) {
41 if (!code.endsWith("}")) {
42 throw new IllegalStateException("The java code not endsWith \"}\", code:
" + code + "
");
43 }
44 try {
45 return doCompile(className, code);
46 } catch (RuntimeException t) {
47 throw t;
48 } catch (Throwable t) {
49 throw new IllegalStateException("Failed to compile class, cause: " + t.getMessage() + ", class: " + className + ", code:
" + code + "
, stack: " + ClassUtils.toString(t));
50 }
51 }
52 }
53
54 protected abstract Class> doCompile(String name, String source) throws Throwable;
55 }
이 방법 은 자바 ssistCompiler 의 Class > doCompile (String name, String source) 방법 을 실행 합 니 다. 이 방법 에 서 는 정규 표현 식 을 사용 하여 들 어 오 는 소스 코드 를 속성 방법 등 으로 해석 하고 자바 ssist 의 API 를 사용 하여 Class > 를 만 듭 니 다.
마지막 으로, 이 최종 프로 토 콜 adaptiveExtension = loader. getAdaptiveExtension ();코드 가 되 돌아 오 는 adaptiveExtension = Protocol $Adaptive 인 스 턴 스.
총화 (다시 한 번 잔소리):
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.