Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
Expand All @@ -35,7 +35,7 @@ jobs:

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: test-results
path: |
Expand All @@ -47,10 +47,10 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7

- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v6
with:
java-version: '17'
distribution: 'temurin'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,33 @@

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

public class ByteBuddyProxyFactory implements ProxyFactory {

private final RpcClient rpcClient;
private volatile RpcClient rpcClient;

public ByteBuddyProxyFactory() {
this.rpcClient = new RpcClient();
// 与 JDK Proxy 一致:SPI 扩展加载阶段不初始化注册中心和传输层。
}

ByteBuddyProxyFactory(RpcClient rpcClient) {
this.rpcClient = Objects.requireNonNull(rpcClient, "rpcClient");
}

private RpcClient getRpcClient() {
RpcClient client = rpcClient;
if (client == null) {
synchronized (this) {
client = rpcClient;
if (client == null) {
client = new RpcClient();
rpcClient = client;
}
}
}
return client;
}

@Override
Expand Down Expand Up @@ -52,7 +71,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
}

RpcRequest request = builder.build();
CompletableFuture<Object> future = rpcClient.sendRequest(request, method.getReturnType());
CompletableFuture<Object> future = getRpcClient().sendRequest(request, method.getReturnType());
// 如果业务接口声明的返回类型是异步的,直接返回 Future;否则阻塞等待结果
if (CompletableFuture.class.isAssignableFrom(method.getReturnType())) {
return future;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,30 @@

public class JdkProxyFactory implements ProxyFactory {

private final RpcClient rpcClient;
private volatile RpcClient rpcClient;

public JdkProxyFactory() {
this(new RpcClient());
// SPI 扩展加载阶段保持轻量,不在构造时初始化注册中心和传输层。
}

JdkProxyFactory(RpcClient rpcClient) {
this.rpcClient = Objects.requireNonNull(rpcClient, "rpcClient");
}

private RpcClient getRpcClient() {
RpcClient client = rpcClient;
if (client == null) {
synchronized (this) {
client = rpcClient;
if (client == null) {
client = new RpcClient();
rpcClient = client;
}
}
}
return client;
}

@Override
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> clazz) {
Expand Down Expand Up @@ -54,7 +68,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
}

RpcRequest request = builder.build();
CompletableFuture<Object> future = rpcClient.sendRequest(request, method.getReturnType());
CompletableFuture<Object> future = getRpcClient().sendRequest(request, method.getReturnType());
// 如果业务接口声明的返回类型是异步的,直接返回 Future;否则阻塞等待结果
if (CompletableFuture.class.isAssignableFrom(method.getReturnType())) {
return future;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ void testLoadBalancerExtensions() {
void testProxyFactoryExtensions() {
ExtensionLoader<ProxyFactory> loader = ExtensionLoader.getExtensionLoader(ProxyFactory.class);

// jdk 代理实现不依赖网络与注册中心,单元测试里直接实例化即可
// ProxyFactory 的 SPI 加载必须保持轻量:rpc-core 本身不包含具体 Transport 实现,
// 因此这里只实例化代理工厂,不能在构造阶段触发 RpcClient/注册中心/网络初始化。
assertNotNull(loader.getExtension("jdk"), "JDK proxy factory should be loaded");
assertNotNull(loader.getExtension("bytebuddy"), "ByteBuddy proxy factory should be loaded");

// bytebuddy 在当前实现里会进一步初始化 RpcClient(包含注册中心/传输层依赖),
// 这里仅校验其扩展声明已被正确加载,避免把单元测试耦合到外部环境
var extensions = loader.getSupportedExtensions();
assertTrue(extensions.contains("jdk"), "Should contain 'jdk' extension");
assertTrue(extensions.contains("bytebuddy"), "Should contain 'bytebuddy' extension");
assertEquals(2, extensions.size(), "Should have exactly 2 proxy factory extensions");
}
Expand Down
Loading