diff --git a/core/src/main/java/com/linecorp/armeria/client/ClientFactoryConfigurator.java b/core/src/main/java/com/linecorp/armeria/client/ClientFactoryConfigurator.java new file mode 100644 index 00000000000..2123326a85b --- /dev/null +++ b/core/src/main/java/com/linecorp/armeria/client/ClientFactoryConfigurator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2026 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package com.linecorp.armeria.client; + +import com.linecorp.armeria.common.annotation.UnstableApi; + +/** + * Configures a built-in default {@link ClientFactory} using the specified {@link ClientFactoryBuilder}. + * + *
This configurator is invoked while creating the built-in default {@link ClientFactory}s returned by + * {@link ClientFactory#ofDefault()} and {@link ClientFactory#insecure()}. + * + *
This configurator is applied to both the default and insecure built-in + * {@link ClientFactory}s, so it must not call + * {@link ClientFactory#ofDefault()} or {@link ClientFactory#insecure()}. + * + *
Because {@link ClientFactory#insecure()} applies {@link ClientFactoryBuilder#tlsNoVerify()} after this + * configurator runs, TLS verification-related customization is unsupported. + */ +@UnstableApi +@FunctionalInterface +public interface ClientFactoryConfigurator { + + /** + * Configures the built-in default {@link ClientFactory} using the specified + * {@link ClientFactoryBuilder}. + * + *
Note that {@link ClientFactoryBuilder#tlsNoVerify()} is applied after this method returns when
+ * creating {@link ClientFactory#insecure()}.
+ */
+ void configureDefault(ClientFactoryBuilder builder);
+
+ /**
+ * Returns a {@link ClientFactoryConfigurator} that does not customize the specified
+ * {@link ClientFactoryBuilder}.
+ */
+ static ClientFactoryConfigurator noop() {
+ return builder -> {
+ };
+ }
+}
diff --git a/core/src/main/java/com/linecorp/armeria/client/DefaultClientFactory.java b/core/src/main/java/com/linecorp/armeria/client/DefaultClientFactory.java
index 9c4cc44aadb..04c35e1e423 100644
--- a/core/src/main/java/com/linecorp/armeria/client/DefaultClientFactory.java
+++ b/core/src/main/java/com/linecorp/armeria/client/DefaultClientFactory.java
@@ -36,6 +36,7 @@
import com.google.common.collect.Streams;
import com.linecorp.armeria.client.endpoint.EndpointGroup;
+import com.linecorp.armeria.common.Flags;
import com.linecorp.armeria.common.Scheme;
import com.linecorp.armeria.common.SessionProtocol;
import com.linecorp.armeria.common.TlsProvider;
@@ -70,11 +71,14 @@ final class DefaultClientFactory implements ClientFactory {
private static volatile boolean shutdownHookDisabled;
+ private static final ClientFactoryConfigurator DEFAULT_CLIENT_FACTORY_CONFIGURATOR =
+ Flags.defaultClientFactoryConfigurator();
+
static final DefaultClientFactory DEFAULT =
- (DefaultClientFactory) ClientFactory.builder().build();
+ newDefaultClientFactory(false, DEFAULT_CLIENT_FACTORY_CONFIGURATOR);
static final DefaultClientFactory INSECURE =
- (DefaultClientFactory) ClientFactory.builder().tlsNoVerify().build();
+ newDefaultClientFactory(true, DEFAULT_CLIENT_FACTORY_CONFIGURATOR);
static {
if (DefaultClientFactory.class.getClassLoader() == ClassLoader.getSystemClassLoader()) {
@@ -94,6 +98,16 @@ static void disableShutdownHook0() {
shutdownHookDisabled = true;
}
+ private static DefaultClientFactory newDefaultClientFactory(boolean insecure,
+ ClientFactoryConfigurator configurator) {
+ final ClientFactoryBuilder builder = ClientFactory.builder();
+ configurator.configureDefault(builder);
+ if (insecure) {
+ builder.tlsNoVerify();
+ }
+ return (DefaultClientFactory) builder.build();
+ }
+
private final HttpClientFactory httpClientFactory;
private final Multimap This value is consulted while initializing the built-in default client factories.
+ *
+ * @see ClientFactoryConfigurator
+ */
+ @UnstableApi
+ public static ClientFactoryConfigurator defaultClientFactoryConfigurator() {
+ final ClientFactoryConfigurator configurator =
+ getValue(FlagsProvider::defaultClientFactoryConfigurator,
+ "defaultClientFactoryConfigurator");
+ return configurator != null ? configurator : ClientFactoryConfigurator.noop();
+ }
+
/**
* Returns the default interval in milliseconds between the reports on unlogged exceptions.
*
diff --git a/core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java b/core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
index fda7fcb9dc8..5de195c5c87 100644
--- a/core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
+++ b/core/src/main/java/com/linecorp/armeria/common/FlagsProvider.java
@@ -33,6 +33,7 @@
import com.linecorp.armeria.client.ClientBuilder;
import com.linecorp.armeria.client.ClientFactoryBuilder;
+import com.linecorp.armeria.client.ClientFactoryConfigurator;
import com.linecorp.armeria.client.DnsResolverGroupBuilder;
import com.linecorp.armeria.client.ResponseTimeoutMode;
import com.linecorp.armeria.client.retry.Backoff;
@@ -822,6 +823,29 @@ default Long defaultRequestAutoAbortDelayMillis() {
return null;
}
+ /**
+ * Returns a {@link ClientFactoryConfigurator} that customizes the built-in default
+ * {@link com.linecorp.armeria.client.ClientFactory}s.
+ *
+ * If {@code null} is returned, the next available {@link FlagsProvider} is consulted. The returned {@link ClientFactoryConfigurator} is applied while creating the built-in default
+ * {@link com.linecorp.armeria.client.ClientFactory}s, so it must not call
+ * {@link com.linecorp.armeria.client.ClientFactory#ofDefault()} or
+ * {@link com.linecorp.armeria.client.ClientFactory#insecure()}. This configurator is applied to both the default and insecure built-in
+ * {@link com.linecorp.armeria.client.ClientFactory}s. Because
+ * {@link com.linecorp.armeria.client.ClientFactory#insecure()} applies
+ * {@link com.linecorp.armeria.client.ClientFactoryBuilder#tlsNoVerify()} after the configurator runs,
+ * TLS verification-related customization is unsupported.