# grpc-spring: wiring gRPC servers and stubs into Spring Boot

> grpc-ecosystem/grpc-spring is a Spring Boot starter that runs a gRPC server from your @GrpcService beans and injects client stubs with @GrpcClient. It fits Spring teams adding a binary RPC surface, and it is the wrong tool if you want Spring Boot 4 or a framework that tracks gRPC releases quickly.

**grpc-ecosystem/grpc-spring** — Spring Boot starter module for gRPC framework.

- Repository: https://github.com/grpc-ecosystem/grpc-spring
- Website: https://grpc-ecosystem.github.io/grpc-spring/
- Stars: 3,709 · Forks: 858
- Language: Java
- License: Apache-2.0
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/grpc-ecosystem-grpc-spring

## The gap grpc-spring fills between grpc-java and Spring Boot

Plain grpc-java gives you a ServerBuilder and a ManagedChannel. Spring Boot gives you dependency injection, configuration properties and lifecycle management. Joining the two by hand means writing a bean that builds the server, registering every BindableService, starting it after the context is ready, and shutting it down on context close. Then you repeat the work for each client channel and stub, and again for every interceptor.

grpc-spring removes that boilerplate. The README states it "Automatically configures and runs the gRPC server with your @GrpcService implementations" and "Automatically creates and manages your grpc channels and stubs with @GrpcClient". The audience is Spring Boot teams that already have protobuf definitions and want the service implementation to be an ordinary Spring bean. It is not aimed at teams running gRPC outside Spring, though the README notes the project "can also be used without Spring-Boot, however that requires some manual bean configuration."

## How the server, client and interceptors are wired

The server side works through classpath scanning. Any bean annotated with @GrpcService is collected and registered with the underlying gRPC server, which the starter configures and starts. The README's example extends GreeterGrpc.GreeterImplBase and overrides sayHello, writing the reply through the StreamObserver. That is the grpc-java service contract, unchanged; the starter only handles registration and lifecycle. Server-side support is described as working for all grpc-java flavors, since they all produce io.grpc.BindableService instances.

The client side is field injection. A field annotated with @GrpcClient("name") receives a stub, and the README warns not to combine it with @Autowired or @Inject. The name is resolved to a target URI. If no NameResolver.Factory bean is configured, the README says the default URI "will be guessed using the default scheme and the name (e.g.: dns:/<name>)". With Spring Cloud, the client reads target addresses from Spring's DiscoveryClient, and on the server side the registration details gain grpc-port information. Native registration support is listed for Consul, Eureka and Nacos, with an explicit request to report others.

Interceptors are supported globally and per client or server. Metrics come through micrometer and actuator, and Spring Sleuth tracing works when brave-instrumentation-grpc is on the classpath. The client side is the narrower part: custom StubFactory implementations are required for non-grpc-java stub flavors, and the README lists only grpc-java as built in, with grpc-kotlin and Reactive gRPC named as flavors the project would like to support.

## Installing grpc-spring and serving your first call

The artifact lives on Maven Central under the net.devh group. For a service that is both a server and a client, the README gives this Maven dependency, with the current release version 3.1.0.RELEASE:

```xml
<dependency>
  <groupId>net.devh</groupId>
  <artifactId>grpc-spring-boot-starter</artifactId>
  <version>3.1.0.RELEASE</version>
</dependency>
```

A server-only application uses the server starter instead. The Gradle form is shown in the README as implementation 'net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE'.

```xml
<dependency>
  <groupId>net.devh</groupId>
  <artifactId>grpc-server-spring-boot-starter</artifactId>
  <version>3.1.0.RELEASE</version>
</dependency>
```

With the dependency present, annotate the implementation of your generated base class. The README's greeter example looks like this:

```java
@GrpcService
public class GrpcServerService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
        HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
        responseObserver.onNext(reply);
        responseObserver.onCompleted();
    }
}
```

Start the application and the server listens on port 9090 by default. That value and other settings are bound under the grpc.server. prefix, so an application.properties or application.yml entry such as grpc.server.port changes it. On the calling side, a field annotated with the server name receives the stub:

```java
@GrpcClient("gRPC server name")
private GreeterGrpc.GreeterBlockingStub greeterStub;
```

Do not put @Autowired or @Inject on that field. The README also notes that the same server name can back multiple channels and different stubs, even ones carrying different interceptors.

## The release cadence is the real constraint

The newest release in the repository is v3.1.0.RELEASE, published on 2024-04-14. Before that came v3.0.0.RELEASE on 2024-02-22 and v2.15.0 on 2023-09-28. The last push to the repository was on 2026-09-07, so work is happening on the branch, but the version you can pull from Maven Central has not moved in roughly two years. The README says 3.1.0.RELEASE was compiled with spring-boot 3.2.4 and spring-cloud 2023.0.0 and claims compatibility with "a large variety of other versions", pointing at a versions page for the mapping.

That gap matters in both directions. Spring Boot and Spring Cloud release lines move on their own schedules, and a starter built against 3.2.4 carries assumptions about auto-configuration and property binding that later minors can change. The related searches include "grpc spring boot 4"; nothing in the README or the release list indicates a Spring Boot 4 build exists. If your platform plan is Spring Boot 4, this project has no published artifact for it, and the versions page is the only place to check what is actually supported.

The second constraint is stub support on the client. If your team writes services in grpc-kotlin or uses Reactive gRPC, the server side should still register because those flavors are BindableService-based, but the client side needs a custom StubFactory that you write and maintain. That is a real cost, not a configuration flag.

## What you give up compared to plain grpc-java

The alternative is grpc-java without a Spring starter, and the difference is who owns the lifecycle. With plain grpc-java you construct the ServerBuilder, bind the port, call start, register a shutdown hook, and build each ManagedChannel yourself. You get exact control over the Netty builder, the executor, keepalive settings and the order in which interceptors attach, and nothing stands between you and a new grpc-java release.

grpc-spring trades that control for declaration. The server starts because the context starts, services register because they are beans, and clients appear because a field is annotated. The cost is indirection: when a channel does not come up, you are debugging the starter's property resolution and NameResolver selection rather than your own builder code. The README's note that the default URI is guessed from the scheme and name is a good example of behaviour that is convenient until it guesses wrong, at which point you supply a NameResolver.Factory bean to take over.

A second alternative worth naming is doing nothing at the RPC layer and exposing REST. The related search "Is gRPC better than REST API?" has no universal answer, and this project does not settle it. grpc-spring makes gRPC cheap to add inside Spring Boot; it does not make gRPC the right transport for browser clients or for teams without protobuf tooling in their build.

## Licence and the cost of staying on 3.1.0.RELEASE

The repository carries the Apache-2.0 licence, which permits commercial use and modification with the usual notice and attribution conditions. That is a permissive licence, but it is not legal advice; read the LICENSE file and your own obligations before shipping.

The upgrade cost is a version-matrix problem. grpc-spring sits between grpc-java, Spring Boot and Spring Cloud, and the README's compatibility claim is backed by a versions page rather than by a support policy. When you bump Spring Boot, you are also implicitly choosing a grpc-java line and a Spring Cloud release train that the starter was compiled against. Because the published artifact has not changed since 2024-04-14, a Spring Boot upgrade that lands past the tested combinations leaves you either pinning older Spring versions or building the starter from source. Budget for that check before you plan a platform migration, not after.

## Conclusion

Adopt grpc-spring if your services are already Spring Boot 3 applications and you want gRPC endpoints declared as beans rather than as a hand-managed ServerBuilder. Do not adopt it if you need Spring Boot 4 support or if you cannot accept a release cadence where the newest artifact is 3.1.0.RELEASE from 2024-04-14. Before committing, check the versions page for your Spring Boot line and confirm whether you need the client starter's StubFactory support for your stub flavor, because grpc-kotlin and RxJava stubs are not built in.

## FAQ

### What is grpc-spring?

It is a Spring Boot starter module for the gRPC framework, published under the net.devh group. It auto-configures a gRPC server from your @GrpcService beans and manages client channels and stubs injected with @GrpcClient.

### How do I add grpc-spring to a Maven project?

Add the net.devh artifact to your dependencies. The README shows groupId net.devh, artifactId grpc-spring-boot-starter and version 3.1.0.RELEASE for a combined server and client, or grpc-server-spring-boot-starter for a server-only application.

### Which port does the grpc-spring server listen on by default?

The README states the gRPC server listens on port 9090 by default. It can be changed through Spring's property mechanism, using the grpc.server. prefix.

### Can I use @GrpcClient together with @Autowired?

No. The README explicitly says not to use @GrpcClient in conjunction with @Autowired or @Inject. The annotation on the field is what supplies the stub.

### Does grpc-spring work with grpc-kotlin or Reactive gRPC stubs?

Server-side support should work for all grpc-java flavors because they are io.grpc.BindableService based. Client-side support requires custom StubFactory implementations, and the README lists only grpc-java as built in.

## Sources

- [grpc-ecosystem/grpc-spring on GitHub](https://github.com/grpc-ecosystem/grpc-spring)
- [License: Apache-2.0](https://github.com/grpc-ecosystem/grpc-spring/blob/master/LICENSE)
- [Project website](https://grpc-ecosystem.github.io/grpc-spring/)
- [README](https://github.com/grpc-ecosystem/grpc-spring/blob/master/README.md)
- [Releases](https://github.com/grpc-ecosystem/grpc-spring/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/grpc-ecosystem-grpc-spring
