Cursor Playbook for Large Java/Spring Codebases
A practical, example-driven guide to set up Cursor, standardize usage with
.cursor/rules, and run high-leverage workflows in big Spring repos.
Use this doc to set up Cursor, align conventions with .cursor/rules, and run safe, fast
workflows in a large Spring repo.
[!TIP]
Core rhythm: Ask → Plan → Apply. Keep context tight using @Files, @Docs, and
selections.
Audience & Goals
● Who: Java/Spring teams working in large/monorepo codebases
● Goal: Faster edits, safer refactors, consistent architecture
1) Setup (Java/Spring in Cursor)
Install these VS Code extensions in Cursor:
● Extension Pack for Java
● Gradle for Java / Maven (per module)
● Spring Boot Extension Pack
● Lombok (if you use it)
Use modes intentionally
● Ask: understand code, propose plans
● Agent / Composer: apply multi-file changes, run shell commands
3 shortcuts to memorize
● Add selection → Chat: Cmd/Ctrl + Shift + L
● Add selection → Edit: Cmd/Ctrl + Shift + K
● New chat from selection: Cmd/Ctrl + L
Pin files/folders with @Files.
Mini example (Ask prompt):
Explain how `OrderService` computes totals.
List the 3–5 files to read before changes and any risky areas.
2) Make Cursor “know” the repo
● Let first-time indexing finish (Settings → Indexing & Docs)
● Add official docs via @Docs: Spring Boot, Spring Security, MapStruct, internal platform
guide
● Use @Web only when external context is truly needed
● In very large monorepos, open only the specific module folder for focused work
Mini example (Docs pin):
@Docs Spring Boot Reference, Spring Security Reference, Company
Platform Guide
3) Codify team knowledge with .cursor/rules
Create .cursor/rules/[Link] so Cursor follows your conventions during
planning & edits.
Keep rules:
● Short, concrete
● Example-rich (patterns, “before/after”)
● Linked to your architecture doc
Starter snippet:
# Spring conventions (Team)
- Constructor injection only; no field injection
- `@Service` on services; `@Transactional` at service layer boundaries
- Controllers return `ResponseEntity<T>`; validate with `@Validated` +
Bean Validation
- Immutable DTOs as `record`; mapping via MapStruct
- Logging with SLF4J; no [Link]; prefer structured logs
- Central errors: `@RestControllerAdvice` using ProblemDetail
- Tests first (`*[Link]`, `*[Link]`)
- Per-module build tool (no mixing Maven/Gradle inside a module)
- Security with Spring Security; method guards via `@PreAuthorize`
- Don’t invent APIs—read code or `@Docs`
[!IMPORTANT]
Rules are the highest-priority signal Cursor follows. This is your biggest leverage
point.
4) Daily context hygiene (small habits → big wins)
● Pin precise context: controller, service, test, and key configs (e.g., SecurityConfig)
● Work as: Ask → Plan → Apply
○ Ask for a step-by-step plan that names files/lines
○ Apply with Agent/Composer
● Use selections so edits land exactly where you intend
● Keep context lean: the 5–10 most relevant files + your rules
Mini example (Ask prompt):
Plan changes to `PaymentController` and `PaymentService` to add
idempotency (Idempotency-Key header).
List files and exact methods to modify. Include test updates.
5) Power workflows
5.1 Repo-wide refactor (safe pattern)
Goal: consistent change across modules (e.g., field → constructor injection)
Steps
1. Ask: request a plan + risks + module list
2. Pin rules + 2–3 representative modules
3. Apply module-by-module; run tests; commit cleanly
Commit titles (tiny examples)
refactor(di): replace field injection with constructors in billing/*
test(di): update mocks for constructor injection
Before → After (micro example)
// BEFORE
@Service class BillingService {
@Autowired private InvoiceRepo repo;
}
// AFTER
@Service class BillingService {
private final InvoiceRepo repo;
BillingService(InvoiceRepo repo) { [Link] = repo; }
}
5.2 Feature thread (new REST endpoint)
Pin
● Controller + Service + DTOs/Mapper
● Security config
● Tests
● .cursor/rules
Ask for design + tests first, then implement; verify with mvn/gradle test.
Tiny controller example
@RestController
@RequestMapping("/orders")
class OrderController {
private final OrderService svc;
OrderController(OrderService svc){ [Link] = svc; }
@PostMapping
ResponseEntity<OrderDto> create(@Valid @RequestBody CreateOrderDto
in){
return [Link]([Link](in));
}
}
5.3 Onboarding & knowledge capture
● Create docs/[Link] with module graph, contracts, data flows
● Reference it in .cursor/rules so edits stay aligned
Mini excerpt example
orders → inventory via InventoryClient (HTTP, retries=3, timeout=1.5s)
6) Java/Spring specifics that boost quality
● Use Spring Boot Dashboard to run/debug multiple services
● Prefer records for immutable DTOs; MapStruct for mapping
● Logging via SLF4J; avoid [Link]
● Validate inputs and secure endpoints up front
Tiny examples
public record OrderDto(String id, BigDecimal total) {}
@Mapper interface OrderMapper {
OrderDto toDto(Order o);
}
7) Validation, errors, and security (mini patterns)
Validation
@Validated
@RestController
class UserController {
@GetMapping("/user")
ResponseEntity<UserDto> get(@RequestParam @NotBlank String id) { ...
}
}
Central error handling (Spring 6+)
@RestControllerAdvice
class ApiErrors {
@ExceptionHandler([Link])
ProblemDetail onBadReq(IllegalArgumentException ex){
var p = [Link](400);
[Link]([Link]());
return p;
}
}
Method security
@EnableMethodSecurity
@Configuration class SecurityConfig {}
@Service
class ReportService {
@PreAuthorize("hasRole('ADMIN')")
Report getAdminReport(){ ... }
}
8) Tests first (keep AI on rails)
● JUnit 5 + Mockito (or your stack)
● Write/modify tests before large edits
● Integration tests use *[Link]
Tiny unit test
class PriceCalcTest {
@Test void totalsAreRounded() {
assertEquals(new BigDecimal("10.00"),
[Link](new BigDecimal("9.995")));
}
}
9) Advanced: Model Context Protocol (MCP)
Wire internal docs/tools (Confluence, internal Swagger, build bots) so Agent can fetch real data
without copy-paste.
Conceptual config sketch
{
"mcpServers": {
"confluence": { "command": "confluence-mcp", "args":
["--site=[Link] },
"swagger": { "command": "swagger-mcp", "args":
["--spec=[Link] }
}
}
[!NOTE]
Configure credentials per your org policy; scope to non-sensitive areas first.
Example:
“Create a Spring controller for POST /orders, and confirm auth rules from Confluence.”
10) Governance & privacy
● Cursor embeds code snippets for semantic search/answers
● Decide allowed repos, redaction strategy, and CI usage
● Policy example (tiny):
“AI assistants may access services/* and libs/*. Exclude secrets/ and
customer-data/. All PRs require human review.”
11) Quick checklist
● Install Java/Spring extensions; ensure tests run locally
● Add .cursor/rules with conventions + examples
● Add @Docs (Spring + internal platform)
● Adopt Ask → Plan → Apply + context pinning
● For huge repos: open focused subfolders / multi-root workspaces
Appendix A — Starter .cursor/rules/[Link]
# .cursor/rules/[Link] (Starter)
- Constructor injection only
- `@Service` on services; `@Transactional` at service layer boundaries
- Controllers return `ResponseEntity<T>`; Bean Validation with
`@Validated`
- DTOs as `record`; MapStruct for mapping
- Logging: SLF4J; no [Link]; use structured logs
- Errors: `@RestControllerAdvice` with ProblemDetail
- Tests first; `*[Link]` / `*[Link]`
- Build: keep a single tool per module (no mixing)
- Security: Spring Security; method security via `@PreAuthorize`
- Do NOT invent APIs—read from code or `@Docs`
## Example pattern: New REST endpoint
- Controller + Service + DTOs + Mapper + Tests + OpenAPI YAML
- Prepare a plan; run tests; commit with clear titles
Appendix B — Shortcuts & context objects
Shortcuts
● Add selection → Chat: Cmd/Ctrl + Shift + L
● Add selection → Edit: Cmd/Ctrl + Shift + K
● New chat from selection: Cmd/Ctrl + L
Context objects
● @Files — pin files/folders
● @Docs — add official/internal docs
● @Web — bring external info only when needed
Pinning example
@Files [Link], [Link], [Link],
[Link]
Appendix C — Ready-to-use prompts
Refactor plan (repo-wide)
Plan a repo-wide refactor to replace field injection with constructor
injection; list risks and files you’ll touch. Follow `.cursor/rules`.
Feature thread (new endpoint)
Design + tests first; then implement controller, service, DTOs,
mapper, security updates. Provide commit messages.
Tight edit in place
Modify only the selected method to add idempotency using
`Idempotency-Key` header. Update tests accordingly.
Appendix D — Micro examples
MapStruct
@Mapper
interface UserMapper {
UserDto toDto(User u);
}
Record DTO
public record UserDto(String id, String name) {}
Commands
# Gradle
./gradlew test
# Maven
mvn -q -DskipITs=false test
What to try today
● Add .cursor/rules (copy the starter and tweak)
● Pin @Docs (Spring + your platform guide)
● Run one refactor (constructor injection in a small module)
● Ship one feature thread with tests first
Example goal:
“Convert billing/ module to constructor injection and keep all tests green.”