Cursor Rules for Java Spring Boot: Examples You Can Adapt

Scoped Cursor rules for Spring Boot projects: architecture, configuration, tests, and dependency choices, with fenbs keeping the project decisions and review work outside reusable rule files.

Updated 5 min read

Cursor rules for Java Spring Boot tell a coding assistant how your project structures its layers, how configuration is managed, which testing framework and patterns are expected, and which library choices are settled. Without them, an assistant uses Spring Boot defaults that may not match your team's decisions: field injection instead of constructor injection, properties mixed with code configuration, or JUnit 4 tests in a project that moved to JUnit 5. fenbs keeps the project's changing decisions and the review work separate from the reusable rule files, so rules stay general while context stays specific.

This guide provides example rules for each area with notes on what to adjust for your project.

How to structure Spring Boot Cursor rules

A Spring Boot project typically has several layers: controllers, services, repositories, and domain or model classes. Each layer has conventions the assistant needs to follow. Rather than one large rule file, separate files scoped to each layer by package or file pattern are easier to maintain and update independently.

Start with one rule file and split it when it becomes hard to maintain. The two rules that give the most immediate value are the injection style rule and the layer separation rule. Once those are in place, add the configuration and test rules. Most Spring Boot projects benefit from four to six rule files rather than one large file or a file per class. See the Cursor rules hierarchy guide for how to layer rules from a shared library file alongside project-specific rule files, so shared conventions stay in one place and project overrides are clearly separated.

  • Architecture rules: which layer goes in which package, and which imports are forbidden across layers.
  • Configuration rules: how beans are defined, how properties are accessed, and how profiles are used.
  • Test rules: which test framework is in use, which annotations to use, and how to isolate layers in tests.
  • Dependency rules: which libraries are approved for each purpose and how to propose a new one.
  • Code style rules: Spring-specific patterns such as injection style, exception handling, and response formats.

Architecture and package rules

Spring Boot makes it easy to create a working application without a deliberate layer structure. An assistant without layer rules will place business logic wherever it fits: sometimes in a service, sometimes in a controller, occasionally in a JPA entity. Rules that name the packages and their responsibilities prevent that drift. A useful first check before applying these rules is to search the codebase for @Autowired field injections and repository calls in controller classes. Both are common in tutorials and quick starts, and finding them gives a concrete list of existing violations the assistant knows to avoid repeating.

Example architecture rules for .cursor/rules/spring-architecture.mdc
# Spring Boot architecture rules

## Package structure
com.example.myapp
  .controller   — REST controllers. No business logic.
  .service      — Business logic and orchestration. No HTTP concerns.
  .repository   — Spring Data repositories and custom queries.
  .domain       — JPA entities and value objects.
  .dto          — Request and response data transfer objects.
  .config       — Spring configuration classes.
  .exception    — Custom exception classes and a global exception handler.

## Layer rules
- Controllers call service methods only. Do not inject repositories into controllers.
- Services may call repositories and other services. No HTTP status logic in services.
- Repository methods use domain language (findByEmail, findActiveOrders), not SQL names.
- Entities do not contain business logic. Keep entities as data holders.

## Injection style
Use constructor injection for all Spring beans.
Do not use @Autowired field injection. It makes testing harder and hides dependencies.
  @Service
  public class OrderService {
    private final OrderRepository orderRepository;
    public OrderService(OrderRepository orderRepository) {
      this.orderRepository = orderRepository;
    }
  }

Configuration rules

Configuration in Spring Boot can scatter between application.properties, application.yml, @Value annotations, @ConfigurationProperties classes, and @Bean methods. A rule that names where each kind of configuration belongs keeps the project readable when someone needs to change a setting.

Example configuration rules
# Spring Boot configuration rules

## Property access
Use @ConfigurationProperties for groups of related properties.
Do not use @Value for more than one or two standalone properties.
Bind properties to a class in the config package:
  @ConfigurationProperties(prefix = "app.mail")
  public class MailProperties { ... }

## Profiles
Environment-specific properties go in application-{profile}.yml.
Profiles: local, dev, staging, prod.
Do not hardcode environment-specific values in Java code; use properties.

## Bean definitions
Define beans in @Configuration classes in the config package.
Do not use @Bean on a component class method unless there is no other option.

## Secrets
Do not commit secrets to application.properties or application.yml.
Secrets are injected through environment variables or a secrets manager.
Reference them as: ${DATABASE_PASSWORD} in the properties file.

Test rules

Spring Boot tests range from lightweight unit tests to full integration tests that start the application context. An assistant without guidance tends to use @SpringBootTest for everything, which starts the entire application for every test and makes the suite slow. Rules that match the test type to the right annotation keep tests fast and informative.

Example test rules
# Spring Boot test rules

## Test framework
This project uses JUnit 5 (Jupiter) and Mockito.
Do not write JUnit 4 tests (@RunWith, @Test from org.junit).

## Choosing the right test type
- Unit tests: use plain JUnit 5 with Mockito for services and domain classes.
  Do not use @SpringBootTest; use @ExtendWith(MockitoExtension.class).
- Controller tests: use @WebMvcTest for the specific controller class.
  Mock the service layer with @MockBean.
- Repository tests: use @DataJpaTest with an in-memory H2 database.
- Integration tests: use @SpringBootTest(webEnvironment = RANDOM_PORT) for full-stack tests only.
  Tag them with @Tag("integration"); they run separately.

## Mocking
Mock external HTTP services with WireMock.
Do not call real external services in unit or integration tests.

## Assertions
Use AssertJ (assertThat) for assertions.
Do not use JUnit's assertEquals; it gives less readable failure messages.

Code style and exception handling rules

Spring Boot projects often have implicit style conventions that only become visible when someone breaks them. A rule that covers the three most common style gaps prevents the most frequent review comments: how exceptions are handled and surfaced, how HTTP response codes are set, and how logging is used. These are areas where an assistant without guidance will write code that works but looks different from the surrounding codebase.

Example style and exception rules
# Spring Boot code style

## Exception handling
Throw typed exceptions from service methods. Do not return null to signal failure.
Catch typed exceptions at the controller level using @ExceptionHandler in a
@RestControllerAdvice class in the exception package.
Do not add try/catch blocks in service methods unless handling a checked exception
from a library that does not use RuntimeException.

## HTTP response codes
Controllers return ResponseEntity<T> with an explicit status.
Use ResponseEntity.ok() for 200, ResponseEntity.created(uri).build() for 201,
ResponseEntity.noContent().build() for 204, and ResponseEntity.notFound().build() for 404.
Do not hardcode status integer values.

## Logging
Use SLF4J. Inject via Lombok @Slf4j or field declaration.
Log at INFO for business-relevant events, DEBUG for diagnostic detail, ERROR for exceptions.
Do not log at INFO inside a loop; use a summary log after the loop.
Do not log request bodies at INFO level; they may contain sensitive data.

Dependency choice rules

Spring Boot projects accumulate dependencies. An assistant asked to add a feature will sometimes pull in a new library for something the project already handles another way. A rule that lists approved libraries for common purposes prevents duplicate dependencies and keeps the build size manageable.

Example dependency rules
# Dependency rules

## Approved libraries by purpose
HTTP client:      Spring WebClient (WebFlux) or RestClient (Spring 6.1+). Not OkHttp or Apache HttpClient.
JSON:             Jackson (already on the classpath via Spring Boot). Not Gson or Moshi.
Validation:       Bean Validation (Hibernate Validator via spring-boot-starter-validation).
Mapping:          MapStruct for DTO mapping. Not ModelMapper.
Logging:          SLF4J with Logback (Spring Boot default). Use log.isDebugEnabled() guards.
Testing mocks:    Mockito. Not PowerMock.
DB migrations:    Flyway. Not Liquibase.

## Adding a new dependency
Before adding a library not in the list, check whether the existing stack covers the need.
Raise a task in fenbs to discuss the addition. Record the decision before committing pom.xml changes.
How fenbs helps

Keep project decisions and review context outside rule files

Cursor rule files are for conventions that apply to all similar work. Project-specific decisions — which Flyway migration version is current, which endpoints have been reviewed, why a dependency exception was approved — belong in fenbs. Record those as Decisions or tasks. The next Cursor session reads both the rules from the file and the project context from fenbs before writing a line of Java.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for your Spring Boot application.
  2. Record the settled dependency choices and architecture decisions in fenbs as standing rules. Include the reason, so future sessions understand why MapStruct was chosen over ModelMapper.
  3. Use fenbs tasks for code review work: a task per PR with the review criteria, what was found, and whether it was resolved. The task links the code change to the decisions behind it.
  4. Connect Cursor to fenbs over MCP from Integrations. Ask it to read the project context before adding a new service, endpoint, or migration.
  5. When a dependency is upgraded or replaced, update the Cursor rule file and record the change as a Decision in fenbs. Both sources should always agree.

For Java rules without the Spring Boot layer, see the Cursor rules Java guide. For organizing multiple rule files across packages, see the Cursor rules hierarchy guide.

Questions people ask.

Should I scope Spring Boot rules to specific packages?

Yes. Scoping architecture rules to src/main/java/**/controller/** and service rules to src/main/java/**/service/** makes them easier to apply selectively. A rule about constructor injection applies everywhere, so set it to alwaysApply: true. A rule about controller response formatting only matters when a controller file is open.

How do I handle rules for a project using Spring Boot 3 versus Spring Boot 2?

State the Spring Boot version in the rule file. Some annotations and APIs changed between major versions. For example, RestTemplate is deprecated in Spring Boot 3 in favor of RestClient or WebClient. A rule that names the version prevents an assistant from using deprecated APIs.

Can Cursor rules help with Spring Security configuration?

Yes. Write a dedicated rule file for security configuration: which SecurityFilterChain pattern is in use, how CORS is configured, which endpoints require authentication, and which authentication providers are used. Security configuration is complex enough to warrant its own focused rule file.

What is the quickest Spring Boot rule to add that gives the most value?

The injection style rule is the fastest win. A single rule that requires constructor injection and forbids @Autowired field injection prevents a class of problem that affects testability across the whole project. Add it first, before the more detailed architecture rules.

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.