0
# Service Providers
1
2
gRPC Core exposes its primary functionality through Java's Service Provider Interface (SPI) mechanism. This allows automatic discovery and registration of core gRPC functionality without requiring direct API calls.
3
4
## Capabilities
5
6
### Load Balancer Provider Registration
7
8
Registers the default pick-first load balancing strategy with the gRPC framework.
9
10
```java { .api }
11
/**
12
* Service registration: META-INF/services/io.grpc.LoadBalancerProvider
13
* Implementation: io.grpc.internal.PickFirstLoadBalancerProvider
14
*/
15
class PickFirstLoadBalancerProvider extends LoadBalancerProvider {
16
/**
17
* Indicates if this provider is available for use
18
* @return true if the provider can be used
19
*/
20
public boolean isAvailable();
21
22
/**
23
* Gets the priority of this provider relative to others
24
* @return priority value (higher numbers indicate higher priority)
25
*/
26
public int getPriority();
27
28
/**
29
* Gets the policy name for this load balancer
30
* @return "pick_first" - the name used in service config
31
*/
32
public String getPolicyName();
33
34
/**
35
* Creates a new load balancer instance
36
* @param helper Helper providing access to channel functionality
37
* @return PickFirstLoadBalancer instance
38
*/
39
public LoadBalancer newLoadBalancer(LoadBalancer.Helper helper);
40
}
41
```
42
43
**Usage:**
44
45
```java
46
import java.util.ServiceLoader;
47
import io.grpc.LoadBalancerProvider;
48
49
// Automatic discovery via SPI
50
ServiceLoader<LoadBalancerProvider> providers = ServiceLoader.load(LoadBalancerProvider.class);
51
for (LoadBalancerProvider provider : providers) {
52
if ("pick_first".equals(provider.getPolicyName())) {
53
LoadBalancer lb = provider.newLoadBalancer(helper);
54
break;
55
}
56
}
57
```
58
59
### Name Resolver Provider Registration
60
61
Registers DNS-based name resolution functionality with the gRPC framework.
62
63
```java { .api }
64
/**
65
* Service registration: META-INF/services/io.grpc.NameResolverProvider
66
* Implementation: io.grpc.internal.DnsNameResolverProvider
67
*/
68
class DnsNameResolverProvider extends NameResolverProvider {
69
/**
70
* Indicates if this provider is available for use
71
* @return true if DNS resolution is available
72
*/
73
protected boolean isAvailable();
74
75
/**
76
* Gets the priority of this provider relative to others
77
* @return priority value for DNS resolution (5 for DNS)
78
*/
79
protected int priority();
80
81
/**
82
* Gets the default URI scheme handled by this provider
83
* @return "dns" - the scheme for DNS-based name resolution
84
*/
85
public String getDefaultScheme();
86
87
/**
88
* Creates a new name resolver for the given target URI
89
* @param targetUri The target URI to resolve (e.g., dns:///example.com:443)
90
* @param args Arguments containing channel configuration
91
* @return DnsNameResolver instance or null if URI is not supported
92
*/
93
public NameResolver newNameResolver(URI targetUri, NameResolver.Args args);
94
95
/**
96
* Returns the socket address types this provider produces
97
* @return Collection containing InetSocketAddress.class
98
*/
99
public Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes();
100
}
101
```
102
103
**Usage:**
104
105
```java
106
import java.net.URI;
107
import java.net.SocketAddress;
108
import java.util.Collection;
109
import java.util.ServiceLoader;
110
import io.grpc.NameResolverProvider;
111
112
// Automatic discovery via SPI
113
URI targetUri = URI.create("dns:///example.com:443");
114
ServiceLoader<NameResolverProvider> providers = ServiceLoader.load(NameResolverProvider.class);
115
116
for (NameResolverProvider provider : providers) {
117
NameResolver resolver = provider.newNameResolver(targetUri, args);
118
if (resolver != null) {
119
resolver.start(listener);
120
break;
121
}
122
}
123
```
124
125
## Service Discovery Process
126
127
gRPC automatically discovers and loads service providers during framework initialization:
128
129
1. **Classpath Scanning**: gRPC scans for `META-INF/services/` files matching interface names
130
2. **Provider Loading**: Service providers are loaded using `ServiceLoader.load()`
131
3. **Priority Ordering**: Providers are ordered by priority (higher numbers first)
132
4. **Availability Check**: Only available providers are considered for use
133
5. **Default Selection**: The highest priority available provider becomes the default
134
135
## Provider Interface Contracts
136
137
### LoadBalancerProvider Contract
138
139
```java { .api }
140
abstract class LoadBalancerProvider {
141
/**
142
* Whether this provider is available for use
143
*/
144
public abstract boolean isAvailable();
145
146
/**
147
* A priority, from 0 to 10 that this provider should be used, higher priority wins
148
*/
149
public abstract int getPriority();
150
151
/**
152
* The policy name for this provider, which makes it selectable via service config
153
*/
154
public abstract String getPolicyName();
155
156
/**
157
* Creates a LoadBalancer for the given helper
158
*/
159
public abstract LoadBalancer newLoadBalancer(LoadBalancer.Helper helper);
160
161
/**
162
* Parses the given LoadBalancingPolicy into configuration for this provider
163
*/
164
public ConfigOrError parseLoadBalancingPolicyConfig(Map<String, ?> rawLoadBalancingPolicyConfig);
165
}
166
```
167
168
### NameResolverProvider Contract
169
170
```java { .api }
171
abstract class NameResolverProvider {
172
/**
173
* Whether this provider is available for use
174
*/
175
protected abstract boolean isAvailable();
176
177
/**
178
* A priority, from 0 to 10 that this provider should be used, higher priority wins
179
*/
180
protected abstract int priority();
181
182
/**
183
* Returns the default scheme for this provider
184
*/
185
public abstract String getDefaultScheme();
186
187
/**
188
* Creates a NameResolver for the given target URI, or null if not supported
189
*/
190
public abstract NameResolver newNameResolver(URI targetUri, NameResolver.Args args);
191
192
/**
193
* Returns the socket address types this provider produces
194
*/
195
public Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes();
196
}
197
```
198
199
## Error Handling
200
201
Service providers handle errors gracefully:
202
203
- **Unavailable Provider**: `isAvailable()` returns false if provider cannot be used
204
- **Unsupported URI**: `newNameResolver()` returns null for unsupported target URIs
205
- **Configuration Errors**: Provider configuration errors are wrapped in `ConfigOrError` objects
206
- **Runtime Errors**: Runtime errors during provider operations are propagated as gRPC Status errors