[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-spring-grpc-spring-boot-4-1":3},{"_id":4,"path":5,"title":6,"description":7,"meta":8,"body":17},"blog\u002Fblog\u002F2026\u002F06\u002F24\u002Fspring-grpc-spring-boot-4-1.md","\u002Fblog\u002F2026\u002F06\u002F24\u002Fspring-grpc-spring-boot-4-1","Getting Started with Spring gRPC in Spring Boot 4.1","Build a gRPC server and client in Spring Boot 4.1 with Spring gRPC — using @GrpcService, protobuf, and the new starters from start.spring.io.",{"slug":9,"date":10,"updatedOn":11,"published":12,"tags":13,"author":14,"cover":15,"video":16,"excerpt":11,"shortDesc":7},"spring-grpc-spring-boot-4-1","2026-06-24T09:00:00.000Z",null,true,[],"Dan Vega","spring-grpc-spring-boot-4-1.jpeg","https:\u002F\u002Fwww.youtube.com\u002Fembed\u002FMPHuBNqbYPM",{"type":18,"value":19,"toc":1024},"minimark",[20,24,31,36,39,42,49,55,61,67,75,79,82,85,128,131,135,154,159,173,275,305,308,312,318,321,338,345,361,368,372,379,563,581,592,596,599,612,638,641,668,675,682,698,704,708,719,728,732,743,758,762,768,817,824,940,943,951,954,958,961,964,967,970,974,981,984,1014,1017,1020],[21,22,23],"p",{},"If you're building microservices in Spring Boot, you've probably relied on REST APIs for all your service-to-service communication. REST is great, and you can ship production-ready APIs with it quickly. But what happens when you need faster wire performance, built-in streaming, or a type-safe contract that works across multiple programming languages? That's where gRPC comes in, and Spring Boot 4.1 makes it a first-class citizen.",[25,26,28],"git-hub-repo",{"url":27},"https:\u002F\u002Fgithub.com\u002Fdanvega\u002Fhello-grpc",[21,29,30],{},"Follow along with the complete working example.",[32,33,35],"h2",{"id":34},"why-grpc-when-rest-already-works","Why gRPC When REST Already Works",[21,37,38],{},"Before writing any code, let's talk about why you should care about gRPC in the first place. You already know how to build REST endpoints in Spring. You've done it a hundred times. So what does gRPC actually buy you?",[21,40,41],{},"Here's where REST starts to show cracks:",[21,43,44,48],{},[45,46,47],"strong",{},"Loose contracts."," You can use OpenAPI to document your REST APIs, but it's optional. Over time, the documentation quietly drifts away from what the code actually does.",[21,50,51,54],{},[45,52,53],{},"Text on the wire."," JSON is human-readable, which is nice for debugging. But it's also verbose. Parsing overhead and payload size add up quickly, especially at scale.",[21,56,57,60],{},[45,58,59],{},"One request at a time."," If you need streaming, you have to bolt on something like Server-Sent Events or WebSockets by hand.",[21,62,63,66],{},[45,64,65],{},"Do-it-yourself clients."," Every consumer of your API rebuilds the client and revalidates the types on their own.",[21,68,69,70,74],{},"gRPC solves all of these problems. It's a contract-first RPC (Remote Procedure Call) framework. You describe your service once in a ",[71,72,73],"code",{},".proto"," file, and then you generate type-safe code for whatever language you're working with: Java, Go, Python, you name it. The data travels as compact binary frames (Protocol Buffers) over a single multiplexed HTTP\u002F2 connection. Server streaming, client streaming, and bidirectional streaming are all built in from day one.",[32,76,78],{"id":77},"what-spring-boot-41-changes","What Spring Boot 4.1 Changes",[21,80,81],{},"In the Java world, gRPC has historically meant a lot of boilerplate. Servers, channels, tests, all wired together by hand. Powerful, but a long way from the smooth Spring Boot experience we're used to.",[21,83,84],{},"Spring gRPC 1.0 came out around the time Spring Boot 4.0 shipped, but some of the niceties weren't there yet. Spring Boot 4.1 rounds out this story and gives us everything we need out of the box:",[86,87,88,102,112,122],"ul",{},[89,90,91,94,95],"li",{},[45,92,93],{},"Server and client starters"," available right from ",[96,97,101],"a",{"href":98,"rel":99},"https:\u002F\u002Fstart.spring.io",[100],"nofollow","start.spring.io",[89,103,104,107,108,111],{},[45,105,106],{},"Auto-configuration"," so you can annotate a bean with ",[71,109,110],{},"@GrpcService"," and it's registered and exposed automatically",[89,113,114,117,118,121],{},[45,115,116],{},"Client injection"," using ",[71,119,120],{},"@ImportGrpcClients"," to inject a type-safe stub, configured like a data source",[89,123,124,127],{},[45,125,126],{},"Test slice"," with in-process transport (no port needed, very fast)",[21,129,130],{},"If you can build a REST app in Spring, you already know how to build a gRPC one.",[32,132,134],{"id":133},"building-the-greeter-server","Building the Greeter Server",[21,136,137,138,141,142,145,146,149,150,153],{},"Let's start from scratch. Head over to ",[96,139,101],{"href":98,"rel":140},[100]," and create a new project. For the metadata, I used ",[71,143,144],{},"dev.danvega"," as the group and ",[71,147,148],{},"server"," as the artifact name. For dependencies, select ",[45,151,152],{},"gRPC Server",". That's all you need. Generate the project, download it, and open it in your favorite IDE.",[155,156,158],"h3",{"id":157},"writing-the-proto-contract","Writing the Proto Contract",[21,160,161,162,164,165,168,169,172],{},"The first thing to do is create your ",[71,163,73],{}," file. This is the contract that defines your service. Create a file called ",[71,166,167],{},"greeter.proto"," in your ",[71,170,171],{},"src\u002Fmain\u002Fproto"," directory:",[174,175,180],"pre",{"className":176,"code":177,"language":178,"meta":179,"style":179},"language-protobuf shiki shiki-themes github-light github-dark github-light","syntax = \"proto3\";\n\noption java_multiple_files = true;\noption java_package = \"dev.danvega.server\";\n\nservice Greeter {\n  rpc SayHello (HelloRequest) returns (HelloReply);\n}\n\nmessage HelloRequest {\n  string name = 1;\n}\n\nmessage HelloReply {\n  string message = 1;\n}\n","protobuf","",[71,181,182,190,196,202,208,213,219,225,231,236,242,248,253,258,264,270],{"__ignoreMap":179},[183,184,187],"span",{"class":185,"line":186},"line",1,[183,188,189],{},"syntax = \"proto3\";\n",[183,191,193],{"class":185,"line":192},2,[183,194,195],{"emptyLinePlaceholder":12},"\n",[183,197,199],{"class":185,"line":198},3,[183,200,201],{},"option java_multiple_files = true;\n",[183,203,205],{"class":185,"line":204},4,[183,206,207],{},"option java_package = \"dev.danvega.server\";\n",[183,209,211],{"class":185,"line":210},5,[183,212,195],{"emptyLinePlaceholder":12},[183,214,216],{"class":185,"line":215},6,[183,217,218],{},"service Greeter {\n",[183,220,222],{"class":185,"line":221},7,[183,223,224],{},"  rpc SayHello (HelloRequest) returns (HelloReply);\n",[183,226,228],{"class":185,"line":227},8,[183,229,230],{},"}\n",[183,232,234],{"class":185,"line":233},9,[183,235,195],{"emptyLinePlaceholder":12},[183,237,239],{"class":185,"line":238},10,[183,240,241],{},"message HelloRequest {\n",[183,243,245],{"class":185,"line":244},11,[183,246,247],{},"  string name = 1;\n",[183,249,251],{"class":185,"line":250},12,[183,252,230],{},[183,254,256],{"class":185,"line":255},13,[183,257,195],{"emptyLinePlaceholder":12},[183,259,261],{"class":185,"line":260},14,[183,262,263],{},"message HelloReply {\n",[183,265,267],{"class":185,"line":266},15,[183,268,269],{},"  string message = 1;\n",[183,271,273],{"class":185,"line":272},16,[183,274,230],{},[21,276,277,278,281,282,285,286,289,290,293,294,289,297,300,301,304],{},"Let's break this down. You define a service called ",[71,279,280],{},"Greeter"," with one RPC method called ",[71,283,284],{},"SayHello",". It takes a ",[71,287,288],{},"HelloRequest"," (which contains a ",[71,291,292],{},"name"," field) and returns a ",[71,295,296],{},"HelloReply",[71,298,299],{},"message"," field). The numeric values (",[71,302,303],{},"1",") represent the positional parameter for each field in the binary encoding.",[21,306,307],{},"This proto file is the single source of truth. If you wanted to share this contract with a Go service, a Python service, or another Java service, you could use this same file to generate type-safe code in each language.",[155,309,311],{"id":310},"generating-the-code","Generating the Code",[21,313,314,315,317],{},"Spring Boot 4.1 includes the protobuf Maven plugin in your project when you select the gRPC Server starter. When you build the project, it generates all the Java classes you need from that ",[71,316,73],{}," file.",[21,319,320],{},"Run a Maven build:",[174,322,326],{"className":323,"code":324,"language":325,"meta":179,"style":179},"language-bash shiki shiki-themes github-light github-dark github-light",".\u002Fmvnw compile\n","bash",[71,327,328],{"__ignoreMap":179},[183,329,330,334],{"class":185,"line":186},[183,331,333],{"class":332},"sZnax",".\u002Fmvnw",[183,335,337],{"class":336},"suV6U"," compile\n",[21,339,340,341,344],{},"After the build completes, check the ",[71,342,343],{},"target\u002Fgenerated-sources\u002Fprotobuf"," directory. You'll see several generated files:",[86,346,347,353,357],{},[89,348,349,352],{},[71,350,351],{},"GreeterGrpc"," (the gRPC service definition)",[89,354,355],{},[71,356,288],{},[89,358,359],{},[71,360,296],{},[21,362,363,364,367],{},"One thing to note if you're using IntelliJ IDEA: you may need to right-click the generated protobuf directory and select ",[45,365,366],{},"Mark Directory as > Generated Sources Root",". Without this step, IntelliJ won't recognize the generated classes in your code.",[155,369,371],{"id":370},"implementing-the-service","Implementing the Service",[21,373,374,375,378],{},"Now create a ",[71,376,377],{},"GreeterService"," class:",[174,380,384],{"className":381,"code":382,"language":383,"meta":179,"style":179},"language-java shiki shiki-themes github-light github-dark github-light","@GrpcService\npublic class GreeterService extends GreeterGrpc.GreeterImplBase {\n\n    @Override\n    public void sayHello(HelloRequest request, StreamObserver\u003CHelloReply> responseObserver) {\n        String message = String.format(\"Hello %s\", request.getName());\n\n        HelloReply reply = HelloReply.newBuilder()\n                .setMessage(message)\n                .build();\n\n        responseObserver.onNext(reply);\n        responseObserver.onCompleted();\n    }\n}\n","java",[71,385,386,396,416,420,428,460,489,493,509,520,530,534,545,554,559],{"__ignoreMap":179},[183,387,388,392],{"class":185,"line":186},[183,389,391],{"class":390},"s-uPX","@",[183,393,395],{"class":394},"sibLe","GrpcService\n",[183,397,398,401,404,407,410,413],{"class":185,"line":192},[183,399,400],{"class":394},"public",[183,402,403],{"class":394}," class",[183,405,406],{"class":332}," GreeterService",[183,408,409],{"class":394}," extends",[183,411,412],{"class":332}," GreeterGrpc.GreeterImplBase",[183,414,415],{"class":390}," {\n",[183,417,418],{"class":185,"line":198},[183,419,195],{"emptyLinePlaceholder":12},[183,421,422,425],{"class":185,"line":204},[183,423,424],{"class":390},"    @",[183,426,427],{"class":394},"Override\n",[183,429,430,433,436,439,442,446,449,451,454,457],{"class":185,"line":210},[183,431,432],{"class":394},"    public",[183,434,435],{"class":394}," void",[183,437,438],{"class":332}," sayHello",[183,440,441],{"class":390},"(HelloRequest ",[183,443,445],{"class":444},"spoOn","request",[183,447,448],{"class":390},", StreamObserver\u003C",[183,450,296],{"class":394},[183,452,453],{"class":390},"> ",[183,455,456],{"class":444},"responseObserver",[183,458,459],{"class":390},") {\n",[183,461,462,465,468,471,474,477,480,483,486],{"class":185,"line":215},[183,463,464],{"class":390},"        String message ",[183,466,467],{"class":394},"=",[183,469,470],{"class":390}," String.",[183,472,473],{"class":332},"format",[183,475,476],{"class":390},"(",[183,478,479],{"class":336},"\"Hello %s\"",[183,481,482],{"class":390},", request.",[183,484,485],{"class":332},"getName",[183,487,488],{"class":390},"());\n",[183,490,491],{"class":185,"line":221},[183,492,195],{"emptyLinePlaceholder":12},[183,494,495,498,500,503,506],{"class":185,"line":227},[183,496,497],{"class":390},"        HelloReply reply ",[183,499,467],{"class":394},[183,501,502],{"class":390}," HelloReply.",[183,504,505],{"class":332},"newBuilder",[183,507,508],{"class":390},"()\n",[183,510,511,514,517],{"class":185,"line":233},[183,512,513],{"class":390},"                .",[183,515,516],{"class":332},"setMessage",[183,518,519],{"class":390},"(message)\n",[183,521,522,524,527],{"class":185,"line":238},[183,523,513],{"class":390},[183,525,526],{"class":332},"build",[183,528,529],{"class":390},"();\n",[183,531,532],{"class":185,"line":244},[183,533,195],{"emptyLinePlaceholder":12},[183,535,536,539,542],{"class":185,"line":250},[183,537,538],{"class":390},"        responseObserver.",[183,540,541],{"class":332},"onNext",[183,543,544],{"class":390},"(reply);\n",[183,546,547,549,552],{"class":185,"line":255},[183,548,538],{"class":390},[183,550,551],{"class":332},"onCompleted",[183,553,529],{"class":390},[183,555,556],{"class":185,"line":260},[183,557,558],{"class":390},"    }\n",[183,560,561],{"class":185,"line":266},[183,562,230],{"class":390},[21,564,565,566,568,569,572,573,576,577,580],{},"That's the entire server implementation. The ",[71,567,110],{}," annotation tells Spring to manage this bean and register it as a gRPC service automatically. You extend ",[71,570,571],{},"GreeterGrpc.GreeterImplBase",", which is the base class generated from your proto file. Then you override ",[71,574,575],{},"sayHello",", pull the name from the request, build a reply, and send it back through the ",[71,578,579],{},"StreamObserver",".",[21,582,583,584,587,588,591],{},"The pattern here is: receive the request, do your work, call ",[71,585,586],{},"onNext()"," with the reply, and then call ",[71,589,590],{},"onCompleted()"," to signal you're done.",[155,593,595],{"id":594},"testing-with-grpc-curl","Testing with gRPC Curl",[21,597,598],{},"Start your application and it will launch on port 9090 by default (gRPC uses Netty under the hood here, not Tomcat).",[21,600,601,602,607,608,611],{},"To test without writing a client, you can use ",[96,603,606],{"href":604,"rel":605},"https:\u002F\u002Fgithub.com\u002Ffullstorydev\u002Fgrpcurl",[100],"gRPCurl",", a command-line tool for interacting with gRPC services. It's like ",[71,609,610],{},"curl"," but for gRPC.",[174,613,615],{"className":323,"code":614,"language":325,"meta":179,"style":179},"grpcurl -plaintext -d '{\"name\": \"Spring\"}' localhost:9090 Greeter\u002FSayHello\n",[71,616,617],{"__ignoreMap":179},[183,618,619,622,626,629,632,635],{"class":185,"line":186},[183,620,621],{"class":332},"grpcurl",[183,623,625],{"class":624},"sECI1"," -plaintext",[183,627,628],{"class":624}," -d",[183,630,631],{"class":336}," '{\"name\": \"Spring\"}'",[183,633,634],{"class":336}," localhost:9090",[183,636,637],{"class":336}," Greeter\u002FSayHello\n",[21,639,640],{},"You should see:",[174,642,646],{"className":643,"code":644,"language":645,"meta":179,"style":179},"language-json shiki shiki-themes github-light github-dark github-light","{\n  \"message\": \"Hello Spring\"\n}\n","json",[71,647,648,653,664],{"__ignoreMap":179},[183,649,650],{"class":185,"line":186},[183,651,652],{"class":390},"{\n",[183,654,655,658,661],{"class":185,"line":192},[183,656,657],{"class":624},"  \"message\"",[183,659,660],{"class":390},": ",[183,662,663],{"class":336},"\"Hello Spring\"\n",[183,665,666],{"class":185,"line":198},[183,667,230],{"class":390},[21,669,670,671,674],{},"You're passing in an RPC request with some data, using plaintext over port 9090, and calling the ",[71,672,673],{},"Greeter.SayHello"," service.",[21,676,677,678,681],{},"If you want to explore what services are available on your server, you can add the gRPC server reflection dependency to your ",[71,679,680],{},"pom.xml"," and then run:",[174,683,685],{"className":323,"code":684,"language":325,"meta":179,"style":179},"grpcurl -plaintext localhost:9090 list\n",[71,686,687],{"__ignoreMap":179},[183,688,689,691,693,695],{"class":185,"line":186},[183,690,621],{"class":332},[183,692,625],{"class":624},[183,694,634],{"class":336},[183,696,697],{"class":336}," list\n",[21,699,700,701,703],{},"This will show you all the available endpoints, including your ",[71,702,280],{}," service, health endpoints, and server reflection endpoints. It's a great way to inspect what your server exposes.",[32,705,707],{"id":706},"building-the-client","Building the Client",[21,709,710,711,714,715,718],{},"For the client, you would head back to ",[96,712,101],{"href":98,"rel":713},[100]," and this time select ",[45,716,717],{},"gRPC Client"," as your dependency.",[21,720,721,722,724,725,727],{},"The client needs the same ",[71,723,73],{}," file. In a production environment, you'd likely store this in a shared module or artifact repository. For a tutorial like this, you can just copy it into the client project's ",[71,726,171],{}," directory.",[155,729,731],{"id":730},"configuring-the-client","Configuring the Client",[21,733,734,735,738,739,742],{},"In your ",[71,736,737],{},"application.properties"," (or ",[71,740,741],{},"application.yml","), configure the channel to point at your server:",[174,744,748],{"className":745,"code":746,"language":747,"meta":179,"style":179},"language-properties shiki shiki-themes github-light github-dark github-light","spring.grpc.client.channels.greeter.target=localhost:9090\n","properties",[71,749,750],{"__ignoreMap":179},[183,751,752,755],{"class":185,"line":186},[183,753,754],{"class":394},"spring.grpc.client.channels.greeter.target",[183,756,757],{"class":390},"=localhost:9090\n",[155,759,761],{"id":760},"injecting-and-using-the-stub","Injecting and Using the Stub",[21,763,764,765,767],{},"On your main application class (or a configuration class), use ",[71,766,120],{}," to import the generated stub:",[174,769,771],{"className":381,"code":770,"language":383,"meta":179,"style":179},"@ImportGrpcClients(@GrpcClient(GreeterGrpc.GreeterBlockingStub.class))\n@SpringBootApplication\npublic class ClientApplication {\n    \u002F\u002F ...\n}\n",[71,772,773,789,796,807,813],{"__ignoreMap":179},[183,774,775,777,780,783,786],{"class":185,"line":186},[183,776,391],{"class":390},[183,778,779],{"class":394},"ImportGrpcClients",[183,781,782],{"class":390},"(@",[183,784,785],{"class":394},"GrpcClient",[183,787,788],{"class":390},"(GreeterGrpc.GreeterBlockingStub.class))\n",[183,790,791,793],{"class":185,"line":192},[183,792,391],{"class":390},[183,794,795],{"class":394},"SpringBootApplication\n",[183,797,798,800,802,805],{"class":185,"line":198},[183,799,400],{"class":394},[183,801,403],{"class":394},[183,803,804],{"class":332}," ClientApplication",[183,806,415],{"class":390},[183,808,809],{"class":185,"line":204},[183,810,812],{"class":811},"s4-Ip","    \u002F\u002F ...\n",[183,814,815],{"class":185,"line":210},[183,816,230],{"class":390},[21,818,819,820,823],{},"Then you can inject the stub and use it. Here's an example using a ",[71,821,822],{},"CommandLineRunner",":",[174,825,827],{"className":381,"code":826,"language":383,"meta":179,"style":179},"@Bean\nCommandLineRunner runner(GreeterGrpc.GreeterBlockingStub greeterStub) {\n    return args -> {\n        HelloRequest request = HelloRequest.newBuilder()\n                .setName(\"Dan Vega\")\n                .build();\n\n        HelloReply reply = greeterStub.sayHello(request);\n        System.out.println(reply.getMessage());\n    };\n}\n",[71,828,829,836,847,860,874,889,897,901,915,931,936],{"__ignoreMap":179},[183,830,831,833],{"class":185,"line":186},[183,832,391],{"class":390},[183,834,835],{"class":394},"Bean\n",[183,837,838,841,844],{"class":185,"line":192},[183,839,840],{"class":390},"CommandLineRunner ",[183,842,843],{"class":332},"runner",[183,845,846],{"class":390},"(GreeterGrpc.GreeterBlockingStub greeterStub) {\n",[183,848,849,852,855,858],{"class":185,"line":198},[183,850,851],{"class":394},"    return",[183,853,854],{"class":390}," args ",[183,856,857],{"class":394},"->",[183,859,415],{"class":390},[183,861,862,865,867,870,872],{"class":185,"line":204},[183,863,864],{"class":390},"        HelloRequest request ",[183,866,467],{"class":394},[183,868,869],{"class":390}," HelloRequest.",[183,871,505],{"class":332},[183,873,508],{"class":390},[183,875,876,878,881,883,886],{"class":185,"line":210},[183,877,513],{"class":390},[183,879,880],{"class":332},"setName",[183,882,476],{"class":390},[183,884,885],{"class":336},"\"Dan Vega\"",[183,887,888],{"class":390},")\n",[183,890,891,893,895],{"class":185,"line":215},[183,892,513],{"class":390},[183,894,526],{"class":332},[183,896,529],{"class":390},[183,898,899],{"class":185,"line":221},[183,900,195],{"emptyLinePlaceholder":12},[183,902,903,905,907,910,912],{"class":185,"line":227},[183,904,497],{"class":390},[183,906,467],{"class":394},[183,908,909],{"class":390}," greeterStub.",[183,911,575],{"class":332},[183,913,914],{"class":390},"(request);\n",[183,916,917,920,923,926,929],{"class":185,"line":233},[183,918,919],{"class":390},"        System.out.",[183,921,922],{"class":332},"println",[183,924,925],{"class":390},"(reply.",[183,927,928],{"class":332},"getMessage",[183,930,488],{"class":390},[183,932,933],{"class":185,"line":238},[183,934,935],{"class":390},"    };\n",[183,937,938],{"class":185,"line":244},[183,939,230],{"class":390},[21,941,942],{},"With the server still running on port 9090, start the client application and you'll see:",[174,944,949],{"className":945,"code":947,"language":948},[946],"language-text","Hello Dan Vega\n","text",[71,950,947],{"__ignoreMap":179},[21,952,953],{},"That's it. The stub is type-safe, configured through properties, and injected like any other Spring bean.",[32,955,957],{"id":956},"rest-vs-grpc-pick-the-right-tool","REST vs. gRPC: Pick the Right Tool",[21,959,960],{},"It's tempting to look at something new like gRPC and want to use it everywhere. Resist that urge. REST, GraphQL, and gRPC are all tools in your toolbox, and each one has trade-offs.",[21,962,963],{},"gRPC shines when you need compact binary payloads for high-throughput service-to-service communication, when you want a contract that's enforced at build time across multiple languages, or when streaming is a core requirement rather than something you're bolting on.",[21,965,966],{},"REST is still a great choice for public-facing APIs, for teams that value human-readable payloads, and for scenarios where browser support matters (gRPC in the browser requires gRPC-Web, which adds complexity).",[21,968,969],{},"The key is understanding what each option can do so you can reach for the right one when the situation calls for it.",[32,971,973],{"id":972},"where-to-go-from-here","Where to Go from Here",[21,975,976,977,580],{},"You've now built a gRPC server and client in Spring Boot 4.1. The full working example, including both projects and a detailed readme with troubleshooting tips, is available in the ",[96,978,980],{"href":27,"rel":979},[100],"GitHub repository",[21,982,983],{},"Some natural next steps to explore:",[86,985,986,992,1002],{},[89,987,988,991],{},[45,989,990],{},"Streaming RPCs",": Try adding server-side or bidirectional streaming to your proto definition",[89,993,994,997,998,1001],{},[45,995,996],{},"Testing",": Use ",[71,999,1000],{},"@AutoConfigureTestGrpcTransport"," to write fast tests with in-process transport",[89,1003,1004,1007,1008,1013],{},[45,1005,1006],{},"The Spring Boot 4.1 release notes",": Check out the ",[96,1009,1012],{"href":1010,"rel":1011},"https:\u002F\u002Fspring.io\u002Fprojects\u002Frelease-highlights",[100],"release highlights"," for more new features beyond gRPC",[21,1015,1016],{},"This is just the first topic in a series covering what's new in Spring Boot 4.1. There's a lot more to explore, and gRPC support is one of the most exciting additions to land in this release.",[21,1018,1019],{},"Happy Coding!",[1021,1022,1023],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sZnax, html code.shiki .sZnax{--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#6F42C1}html pre.shiki code .suV6U, html code.shiki .suV6U{--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#032F62}html pre.shiki code .s-uPX, html code.shiki .s-uPX{--shiki-default:#24292E;--shiki-dark:#E1E4E8;--shiki-sepia:#24292E}html pre.shiki code .sibLe, html code.shiki .sibLe{--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#D73A49}html pre.shiki code .spoOn, html code.shiki .spoOn{--shiki-default:#E36209;--shiki-dark:#FFAB70;--shiki-sepia:#E36209}html pre.shiki code .sECI1, html code.shiki .sECI1{--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#005CC5}html pre.shiki code .s4-Ip, html code.shiki .s4-Ip{--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-sepia:#6A737D}",{"title":179,"searchDepth":192,"depth":192,"links":1025},[1026,1027,1028,1034,1038,1039],{"id":34,"depth":192,"text":35},{"id":77,"depth":192,"text":78},{"id":133,"depth":192,"text":134,"children":1029},[1030,1031,1032,1033],{"id":157,"depth":198,"text":158},{"id":310,"depth":198,"text":311},{"id":370,"depth":198,"text":371},{"id":594,"depth":198,"text":595},{"id":706,"depth":192,"text":707,"children":1035},[1036,1037],{"id":730,"depth":198,"text":731},{"id":760,"depth":198,"text":761},{"id":956,"depth":192,"text":957},{"id":972,"depth":192,"text":973}]