skip to content

Spring for GraphQL

3 roadmaps34 questionsupdated

Spring's GraphQL support: schema-first development, annotated controllers, batch loading to avoid N+1, transports and interception, federation, error handling and cursor pagination. Interviewers ask about GraphQL wherever a single client needs flexible reads over many services.

on this pageshow

guide

overview

~1 min

Spring for GraphQL is the Spring portfolio's GraphQL server, built on the GraphQL Java engine and auto-configured by Spring Boot. You describe the API in a schema, bind its fields to annotated controller methods, and the framework executes each incoming query against that wiring. Interviewers bring it up when a design has one client needing flexible reads across many entities or services, and they probe whether you understand what GraphQL moves around: the client decides the shape of the response, so the server has to cope with query shapes it never planned for. The hub follows that path. [Schema-first development](/topics/be-spring-ecosystem-graphql-schema-first) covers the contract and how it is wired to code; [annotated controllers](/topics/be-spring-ecosystem-graphql-controllers) are where handlers live. [Batch loading and DataLoader](/topics/be-spring-ecosystem-graphql-batch-loading) answers the performance question GraphQL invites by design. [Transports and interception](/topics/be-spring-ecosystem-graphql-transports) explain how requests arrive and how headers and security reach a resolver. [Error handling](/topics/be-spring-ecosystem-graphql-errors) and [cursor-based pagination](/topics/be-spring-ecosystem-graphql-pagination) are where GraphQL conventions differ most from REST, and [federation](/topics/be-spring-ecosystem-graphql-federation) is the answer when many teams sit behind one API. Junior rounds stay on the mapping from schema to method. Senior and principal rounds turn to cost and ownership: batching, partial failures, paging under concurrent writes, and who owns which type once the schema is split across services. Learn the schema and controllers first; everything else in the hub is a refinement of that binding.

primer

### The schema is the contract The SDL files are the API. Clients, reviewers and tooling read them; Java or Kotlin code only supplies values for what they declare. Because nothing ties the two together at compile time, a mismatch shows up at startup or at request time rather than in the compiler, which is why interviewers ask how you keep schema and handlers honest. ### Every field has a resolver Execution walks the query tree and asks a data fetcher for each selected field. Root fields under `Query`, `Mutation` and `Subscription` map to controller methods; fields on other types either come straight from the parent object's properties or from a method that receives that parent. Thinking per field, not per endpoint, is the shift from REST that most other answers depend on. ### The client picks the shape, the server pays for it A client can nest lists inside lists, so a naive per-field lookup multiplies into one call per parent. Batching those lookups per request belongs in the design of any field that crosses a table or a service boundary, not in a later tuning pass. Depth, cost and page-size limits belong to the same conversation. ### Failure is per field One request can succeed in part. A failing field becomes null plus an entry in the `errors` list, while its siblings still return, and the transport status usually stays 200. Error design therefore means choosing classifications and messages clients can act on, and deciding what a client sees when something unexpected breaks. ### One execution, several transports Queries and mutations normally travel over HTTP; subscriptions need a connection that stays open. Interceptors sit in front of execution on every transport, which makes them the place to move headers, identities and correlation ids into the context a resolver can read. ### A graph can have many owners Federation splits one schema across services, each owning some types and extending others by key. It trades a single codebase for composition rules, a router and cross-service query plans — worth it when team boundaries, not load, are the problem.

SDL
Schema Definition Language: the textual syntax for GraphQL types, fields and operations. Spring for GraphQL reads it from .graphqls files on the classpath.
Data fetcher
The GraphQL Java callback that produces the value of one field. Annotated controller methods are registered as data fetchers for the fields they map.
GraphQlSource
The Spring bean that holds the built schema and its runtime wiring, and gives the rest of the framework access to the GraphQL Java engine.
N+1 problem
One call to fetch a list followed by a separate call per item to resolve a related field; GraphQL's nested queries make it easy to trigger.
DataLoader
A per-request utility that queues keys requested by many resolvers, loads them in one batch, deduplicates them and caches the results for that request.
Batch mapping
A controller method that resolves one field for a whole list of parents in a single call, backed by a DataLoader the framework registers.
Subscription
A GraphQL operation that returns a stream of results over time instead of one response, carried over a long-lived connection such as WebSocket.
Interceptor
A chained component wrapping each GraphQL request on a transport, able to read transport details, add context for resolvers and adjust the response.
GraphQLContext
A per-request map shared across the execution. Interceptors write values into it and controller methods can read them as parameters.
Partial response
A result carrying both data and errors: fields that failed are null and described in the errors list, while other fields keep their values.
Connection
The Relay pagination shape: a wrapper holding edges, each an item with its cursor, plus page information describing whether more results exist.
Cursor
An opaque string that marks a position in an ordered result, so the next page starts after it rather than after a row count.
Subgraph
One service's slice of a federated schema, owning some types and fields and able to contribute fields to entities defined elsewhere.
Entity
A federated type with a key that several subgraphs can reference and extend, resolved in each subgraph from that key.

Follow one request. It arrives on the HTTP endpoint (or, for a subscription, on a WebSocket or RSocket connection) and passes through the interceptor chain, which can lift headers or the authenticated user into the request context. The execution engine parses and validates the query against the schema that `GraphQlSource` built at startup, then resolves fields top-down: root fields call controller methods, nested fields call schema mappings or read properties of the parent. Whenever a resolver asks for data through a DataLoader, its key waits in a queue until the engine dispatches the whole level as one batch. Exceptions from any resolver pass through the exception-resolution chain and become entries in `errors` next to whatever data did resolve. The rest of the hub attaches to that path: - **Pagination** wraps selected list fields so a controller can return a scrolled window of results and the framework renders it as a connection with cursors. - **Security** usually authenticates at the endpoint with the ordinary filter chain and authorizes per method, relying on the context reaching resolvers that run asynchronously. - **Federation** adds entity resolution to a subgraph, so a router can ask this service for objects by key in the middle of a plan that spans others. The core binding, with the batching that keeps it from turning into N+1: ```kotlin @Controller class BookController(private val books: BookRepository, private val authors: AuthorClient) { @QueryMapping // Query.booksByGenre in schema.graphqls fun booksByGenre(@Argument genre: String): List<Book> = books.findByGenre(genre) @BatchMapping // Book.author for every book in the response, one call fun author(books: List<Book>): Map<Book, Author> { val byId = authors.findByIds(books.map { it.authorId }.toSet()) return books.associateWith { byId.getValue(it.authorId) } } } ``` The two methods meet only through the schema: nothing in the code says that `Book` has an `author` field, so renaming either side without the other breaks the binding, not the build.

  1. Schema-First Development →

    The contract comes first: SDL files, where they live and how the schema is built and wired to code.

  2. Annotated Controllers →

    How handler methods bind to query, mutation, subscription and nested fields, and how arguments reach them.

  3. Batch Loading & DataLoader →

    The N+1 problem and batching, the most common GraphQL performance question once controllers are clear.

  4. Error Handling →

    Partial responses and exception mapping, where GraphQL behaviour departs furthest from REST habits.

  5. Transports & Interception →

    Endpoints, subscriptions and interceptors: how headers and security context reach a resolver.

  6. Cursor-Based Pagination →

    Relay connections and cursor paging, which build on controllers and on keyset scrolling ideas.

  • Adding a nested field resolved per parent and forgetting batching; it looks fine in a test with three rows and falls over with a real list.

  • Saying a failed GraphQL request returns 4xx or 5xx: a resolver exception usually yields a 200 with null data for that field and an entry in errors.

  • Leaking exception messages to clients, or assuming Spring does it for you: unhandled exceptions are masked as internal errors, so useful errors need explicit mapping.

  • Reading security or headers from a thread-local inside a resolver and being surprised when async execution loses it; move values through interceptors and the request context.

  • Paging with offsets on a list that changes under the reader, or sorting cursor pages by a non-unique column, then wondering why rows repeat or vanish.

  • Proposing federation for a single team's service; its composition, router and cross-service query plans only pay off when ownership is split.

This guide assumes Spring for GraphQL on Spring Boot 3, from 1.3 onward. The project reached 1.0 in 2022 alongside Spring Boot 2.7, and several features interviewers ask about arrived later: - **1.2** added pagination support — connection types, scrolling subranges and adapters over Spring Data's scroll results — along with `@GraphQlExceptionHandler` methods and the schema inspection report that flags schema fields with no handler. - **1.3** added federation support, built on the federation library for GraphQL Java, with entity mapping methods on controllers. If an interviewer's codebase is older, say which features it would lack rather than assuming them. The annotation model for queries, mutations, schema mappings and batch mappings has been stable since 1.0, so answers about controllers and batching carry across every release line.

Spring for GraphQL sits on GraphQL Java, the engine that parses, validates and executes queries; Spring contributes the Boot auto-configuration, the annotated controller model, transports, interception, security integration and Spring Data support. Netflix DGS is the other widely used GraphQL framework for Spring applications, with its own annotation model and code generation around the same engine; a candidate should know both exist and that the concepts transfer. GraphQL itself is usually weighed against REST and gRPC. REST keeps HTTP caching, status codes and simple per-resource endpoints; gRPC suits typed service-to-service calls; GraphQL fits clients that assemble varied views from many entities in one round trip, at the price of harder caching and per-field cost control. In federated designs, Spring services act as subgraphs behind a router such as Apollo's, which owns composition and query planning. See [Federation Overview](/topics/be-spring-ecosystem-graphql-federation) for the subgraph side.

explore

report an issue with this guide →

questions

page 1 of 2

What is the N+1 problem in a GraphQL API, and how does batch loading solve it?

level: juniorimportance: must knowfreq 58%

answer

  1. 1 + N round trips
  2. field resolvers run per-item
  3. defer, collect keys, dispatch once
  4. GraphQL can't auto-JOIN
  5. @BatchMapping or DataLoader

basics

~20 s

When a query returns a list of N items and each item triggers its own lookup for a related field, you get 1 query for the list plus N extra queries. Batch loading collects those N lookups and runs them as one query.

solid answer

~40 s

GraphQL resolves each field independently, so a query returning N books where each book resolves its author fires 1 query for the books plus N separate author queries — the classic N+1 problem. Because it is data-source agnostic, GraphQL cannot auto-join like SQL. Batch loading fixes this: instead of resolving each author immediately, the resolver registers the author key and returns a deferred value. Once all N books have registered their keys, the framework dispatches a single batched call (e.g. findAllById(authorIds)) and hands each field its result. In Spring for GraphQL you get this with @BatchMapping controller methods or a DataLoader registered via BatchLoaderRegistry. It collapses N+1 into 2 round trips regardless of N.

go deeper

for a junior

Must be able to define N+1 and say batching turns 1+N into 2 queries.

for a middle

Should connect it to Spring's @BatchMapping / DataLoader and explain deferred resolution.

for a senior

Should discuss demand-driven fetching and correlating batch results back to keys.

for a principal

Frames it as an architectural constraint of GraphQL's field-resolution model and the tradeoff vs eager fetching.

## The problem A GraphQL query like: ```graphql { books { title author { name } } } ``` resolves fields top-down and independently. Spring for GraphQL first runs the `books` resolver (1 query → N books). Then, for **each** book, it runs the `author` field resolver — and if that resolver naively does `authorRepository.findById(book.authorId())`, you fire **N** more queries. Total: **1 + N** = the **N+1 problem**. With 100 books that is 101 database round trips. GraphQL is **data-source agnostic** — the engine has no idea your `author` field maps to a foreign key, so unlike a hand-written SQL `JOIN` it cannot fold the lookups together automatically. You must do it. ## How batch loading fixes it The core trick is **deferred (lazy) resolution**. Instead of loading the author immediately, the field resolver: 1. Records the **key** it needs (the `authorId`) and returns a **promise/future** that is not yet completed. 2. The GraphQL engine keeps resolving sibling fields, so all N books register their author keys. 3. When the engine finishes that level and is about to dispatch, it calls your **batch function once** with the full list of keys: `[id1, id2, … idN]`. 4. Your batch function runs a single query — `findAllById(authorIds)` — and returns the results; the engine completes each book's future with the matching author. Result: **2** round trips (books + authors) instead of **1 + N**. ## In Spring for GraphQL Two built-in mechanisms: - **`@BatchMapping`** — a controller method that receives a `List<Book>` (all the parents at that level) and returns a `Map<Book, Author>` (or an ordered `List<Author>`). Spring wires it to a DataLoader for you. - **`DataLoader` + `BatchLoaderRegistry`** — register a batch function manually; the resolver calls `dataLoader.load(key)` and returns the resulting `CompletableFuture`. ## Why not just eager-fetch everything? Because the client chooses the shape at runtime. You do not know in advance whether the client will even ask for `author`, so you cannot bake a JOIN into every query. Batch loading is demand-driven: it only batches the fields the client actually requested. ## Gotchas - Batching only helps when the same field is resolved for **many parents at the same level** — a single-object query sees no benefit. - The batch result must be **correlated back** to each key (by map key or by list position); a mismatch silently returns wrong/null data.

  • Why can't GraphQL just do a JOIN automatically like SQL does?
    GraphQL is data-source agnostic — the engine only sees field resolvers, not tables or foreign keys. It has no knowledge that `author` corresponds to a joinable column, so the developer must supply the batching strategy.
  • Does batch loading help a query that returns a single book?
    No. Batching only collapses many lookups at the same level into one. With a single parent there is exactly one author lookup, so there is nothing to batch — the benefit scales with N.

context

open as a page

In Spring for GraphQL, how do @QueryMapping and @MutationMapping map controller methods to schema fields, and how does @Argument bind incoming arguments?

level: juniorimportance: must knowfreq 78%

basics

~10 s

Put @QueryMapping or @MutationMapping on a method in a @Controller; the method name matches the schema field under the Query or Mutation type. @Argument binds a named GraphQL argument to a method parameter.

open as a page

In Spring for GraphQL, what happens to the response when a single data fetcher throws an exception?

level: juniorimportance: must knowfreq 42%

basics

~10 s

Spring catches the exception, sets that field to null, and adds an entry to the top-level "errors" array in the response. Other fields that resolved successfully still return their data — a partial response.

open as a page

What is Relay-style cursor-based pagination in Spring for GraphQL, and what do the Connection, Edge, and PageInfo types represent?

level: juniorimportance: must knowfreq 42%

basics

~20 s

It is a standard way to page a list using opaque cursors instead of page numbers. A Connection wraps Edges; each Edge has a node (the item) plus its cursor; PageInfo carries hasNextPage/hasPreviousPage and start/end cursors.

open as a page

What is schema-first GraphQL development in Spring for GraphQL, and where do you put the schema files?

level: juniorimportance: must knowfreq 70%

basics

~10 s

You write the GraphQL schema by hand in SDL (.graphqls) files. Spring Boot loads them from classpath:graphql/ by default and builds the schema from them; your Java code just supplies the data.

open as a page

How does Spring for GraphQL expose the GraphQL API over HTTP, and how do you enable the GraphiQL UI for exploring it?

level: juniorimportance: must knowfreq 45%

basics

~10 s

Spring for GraphQL serves a single endpoint at POST /graphql. GraphiQL is a built-in in-browser query playground, disabled by default; enable it with spring.graphql.graphiql.enabled=true, then open /graphiql.

open as a page

How does the @BatchMapping annotation work in Spring for GraphQL, and what can the method's signature look like?

level: middleimportance: must knowfreq 48%

basics

~20 s

@BatchMapping marks a controller method that resolves one field for a whole batch of parent objects at once. It receives a List of the parents and returns either a Map from parent to value or a List of values in the same order, so the field is loaded in a single call instead of one per parent.

open as a page

What does @SchemaMapping do for nested/field-level resolution, and how does the parent (source) object get injected?

level: middleimportance: must knowfreq 62%

basics

~20 s

@SchemaMapping resolves a field on a non-root type — for example the author field of a Book. Spring injects the parent object (the Book) as a method parameter so you can compute the child value.

open as a page

How do you map a custom exception to a specific GraphQLError using DataFetcherExceptionResolver / DataFetcherExceptionResolverAdapter?

level: middleimportance: must knowfreq 45%

basics

~10 s

Register a bean that extends DataFetcherExceptionResolverAdapter and override resolveToSingleError (or resolveToMultipleErrors). Build a GraphQLError with GraphqlErrorBuilder, set an ErrorType and message. Return null for exceptions you don't handle so the next resolver tries.

open as a page

What are the _service and _entities fields in a federated subgraph, and what does each do?

level: middleimportance: must knowfreq 55%

basics

~10 s

Every federated subgraph auto-exposes two special query fields. _service { sdl } returns the subgraph's schema as text so it can be composed. _entities(representations:[_Any!]!) takes references (like {__typename, id}) and returns the full objects.

open as a page

How do you implement a federated subgraph in Spring for GraphQL, including entity resolution?

level: seniorimportance: must knowfreq 50%

basics

~20 s

Add Spring for GraphQL's federation support, register a FederationSchemaFactory bean and wire it into the GraphQlSource builder, mark your type with @key in the schema, and add a controller method annotated @EntityMapping that returns the entity for a given key.

open as a page

What is WebGraphQlInterceptor and how do you use it to read an incoming HTTP header and make its value available to a data fetcher?

level: seniorimportance: must knowfreq 34%

basics

~20 s

WebGraphQlInterceptor is a bean that wraps every web GraphQL request. In intercept(request, chain) you read request.getHeaders(), put a value into the GraphQLContext (via request.configureExecutionInput or an attribute), then a data fetcher reads it with @ContextValue.

open as a page

What is Apollo Federation in GraphQL, and what problem does it solve?

level: juniorimportance: should knowfreq 45%

basics

~10 s

Federation lets several small GraphQL services (subgraphs) be combined into one big schema (a supergraph). A router sits in front so clients query one endpoint, while each team owns and runs its own service.

open as a page

How does Spring for GraphQL turn the incoming first/after/last/before arguments into a controller method parameter? Explain ScrollSubrange and Subrange.

level: middleimportance: should knowfreq 33%

basics

~20 s

You declare a ScrollSubrange parameter on the controller method. Spring parses first/after (or last/before) into it, exposing the decoded position (a Spring Data ScrollPosition), the count, and a forward flag you pass to your query.

open as a page

How does Spring Boot turn your .graphqls files into a working schema — what is GraphQlSource and how are fields wired to code?

level: middleimportance: should knowfreq 55%

basics

~10 s

The auto-configured GraphQlSource bean reads the SDL files, builds the GraphQLSchema, and applies the runtime wiring. Annotated controllers (@QueryMapping, @MutationMapping, @SchemaMapping) become the data fetchers for each schema field.

open as a page

Which transports does Spring for GraphQL support for subscriptions, and why can't a plain HTTP POST /graphql handle them the way it handles queries and mutations?

level: middleimportance: should knowfreq 35%

basics

~10 s

Subscriptions stream many results over time, so they need a persistent connection: WebSocket (the graphql-transport-ws protocol) or RSocket. A single request/response HTTP POST returns once and closes, so it can't push an ongoing stream.

open as a page

How do you register and use a DataLoader via BatchLoaderRegistry in Spring for GraphQL, and how does a resolver consume it?

level: seniorimportance: should knowfreq 36%

basics

~20 s

Inject the BatchLoaderRegistry bean and register a batch function for a key/value type pair (registerMappedBatchLoader or registerBatchLoader). Spring adds that DataLoader to each request. A @SchemaMapping resolver then calls dataLoader.load(key) and returns the CompletableFuture; Spring dispatches all keys in one batched call.

open as a page

How does @SubscriptionMapping work and why must its handler return a streaming Publisher (Flux)?

level: seniorimportance: should knowfreq 40%

basics

~20 s

@SubscriptionMapping resolves a field under the Subscription root type. Because a subscription pushes many values over time, the method returns a Flux (or any Reactive Streams Publisher); each emitted item is delivered to the client as a separate result.

open as a page

What is Spring's ErrorType enum, how does it surface to clients, and why does an unhandled exception show as INTERNAL_ERROR?

level: seniorimportance: should knowfreq 34%

basics

~10 s

ErrorType is Spring's enum of error categories (BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, NOT_FOUND, INTERNAL_ERROR) implementing graphql-java's ErrorClassification. It appears to clients under extensions.classification. Unhandled exceptions default to INTERNAL_ERROR with a masked message for security.

open as a page

What is @GraphQlExceptionHandler and how does controller-local versus global (@ControllerAdvice) handling differ?

level: seniorimportance: should knowfreq 38%

basics

~20 s

@GraphQlExceptionHandler marks a method that maps a matching exception to a GraphQLError (or list). Put it in a @Controller for that controller's fetchers only, or in a @ControllerAdvice class to handle exceptions globally across all controllers.

open as a page

Explain the core federation directives @key, @external, @requires, and @provides.

level: seniorimportance: should knowfreq 40%

basics

~20 s

@key names the field(s) that identify an entity so it can be shared across subgraphs. @external marks a field defined elsewhere. @requires says a resolver needs certain external fields. @provides promises a field is already available on a returned entity.

open as a page

You return a Spring Data Window<Book> from a resolver, yet the client receives edges, cursors, and pageInfo. What machinery produces that? Explain ConnectionFieldTypeVisitor and ConnectionAdapter.

level: seniorimportance: should knowfreq 28%

basics

~20 s

A GraphQL type visitor, ConnectionFieldTypeVisitor, wraps the field's DataFetcher. When the resolver returns a Window (detected by a ConnectionAdapter), the visitor converts it into edges (node + cursor per item) and PageInfo, encoding each cursor from the item's ScrollPosition.

open as a page

Compare KeysetScrollPosition and OffsetScrollPosition for GraphQL cursor paging, explain forward vs backward paging, and why the sort must be unique and stable.

level: seniorimportance: should knowfreq 26%

basics

~20 s

Offset positions seek by row count (LIMIT/OFFSET) — simple but shifts under writes and is slow deep in the list. Keyset positions seek by the last row's sort-key values — stable and fast, but the sort must be unique or rows get skipped or duplicated.

open as a page

What is RuntimeWiringConfigurer and when do you need one instead of just annotated controllers?

level: seniorimportance: should knowfreq 45%

basics

~20 s

RuntimeWiringConfigurer is a bean that customizes how the schema is wired at build time. You add one to register custom scalar types, TypeResolvers for interfaces/unions, or directive wiring — things annotated @QueryMapping controllers can't express.

open as a page

How do you enforce authentication/authorization in a Spring for GraphQL app, and how does the Spring Security context reach a data fetcher that may run on a different thread?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Authenticate at the /graphql endpoint with Spring Security's normal HTTP filter chain. Authorize per field with @PreAuthorize on controller methods. Spring for GraphQL propagates the SecurityContext to data fetchers via context propagation, so method security still works even off-thread.

open as a page

Explain how deferred resolution lets Spring for GraphQL batch dependent fetches into a single call. What triggers the dispatch, and what are the ordering and caching semantics?

level: principalimportance: should knowfreq 20%

basics

~20 s

Each field resolver returns an incomplete future after registering its key instead of loading immediately. The GraphQL engine keeps resolving fields at the current level; once it can make no more progress it dispatches every DataLoader once with all queued keys, runs each batch function a single time, and completes the futures. Keys are deduplicated and cached per request.

open as a page

What async/reactive return types can annotated GraphQL controller methods use, and how does Spring treat Mono vs Flux across query, subscription, and field mappings?

level: principalimportance: should knowfreq 30%

basics

~20 s

Handlers may return a plain value, a Mono, a Flux, or a CompletableFuture. Mono/CompletableFuture resolve one value asynchronously. For a query, a Flux is collected into a list; for a subscription, a Flux is streamed. Kotlin suspend functions and Flow are also supported.

open as a page

Explain the full exception-resolution chain in Spring for GraphQL and how you design partial per-field error behavior for a list query.

level: principalimportance: should knowfreq 22%

basics

~20 s

When a fetcher throws, Spring runs an ordered resolver chain (controller-local @GraphQlExceptionHandler, then @ControllerAdvice, then DataFetcherExceptionResolver beans, then the masked INTERNAL_ERROR default). Each error carries a path, so a failing element in a list produces one error while sibling elements still return data — a partial response.

open as a page

How does a supergraph get composed and how does the router plan a query across subgraphs, and where can it go wrong at scale?

level: principalimportance: should knowfreq 28%

basics

~20 s

Composition merges every subgraph's SDL into one supergraph schema at build time, failing if they're incompatible. At runtime the router builds a query plan — which subgraphs to call, in what order, using _entities to join by @key — then executes and merges. Risks: N+1 entity fetches, deep dependency chains, and composition conflicts.

open as a page

What is @ProjectedPayload in Spring for GraphQL, and when would you use it instead of binding an @Argument to a POJO?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

@ProjectedPayload marks an interface used to read GraphQL input arguments. Instead of binding to a concrete class, Spring creates a proxy over the raw argument map, and you access values through getter-style accessor methods on the interface.

open as a page

showing 1–30 of 34