Where can @DisabledInAotMode be applied, and what changed across Spring versions?
answer
- 6.1 class-level introduced
- 6.2 method-level + reason string value()
- context-scoped incompatibility -> class level
- narrow method exception -> method level
- usable as meta-annotation
basics
~10 sIt can be placed on a test class or, in newer Spring, on individual test methods. Class-level use came in Spring 6.1; Spring 6.2 added method-level use and an optional reason string.
solid answer
~40 s@DisabledInAotMode was introduced in Spring Framework 6.1 and originally targeted test classes, disabling the whole class in AOT mode and excluding it from AOT artifact generation. Spring Framework 6.2 broadened it: you can now apply it to individual test methods, and it accepts an optional String value() giving a human-readable reason that shows up in the skip report. Class-level use is the common choice when the whole context is mock-driven; method-level use is handy when only one method mutates the context while sibling methods are AOT-compatible. It can also be used as a meta-annotation to build a custom composed annotation. Practically: annotate the class when the context config itself is AOT-incompatible, and prefer method-level only for narrow exceptions.
code
java · 12 linesimport org.springframework.test.context.aot.DisabledInAotMode;
import org.junit.jupiter.api.Test;
class MixedTests {
@Test
void aotFriendly() { /* runs in AOT mode too */ }
@Test
@DisabledInAotMode("dynamically registers a bean; not AOT-safe") // method-level: Spring 6.2+
void mutatesContext() { /* skipped only in AOT mode */ }
}go deeper
Know it goes on a test class (and, in newer Spring, methods).
State the 6.1 class-level / 6.2 method-level+reason split and when to pick each.
Advise class-level for context-scoped incompatibility and method-level for narrow exceptions to keep coverage.
Consider meta-annotation composition and version constraints across a multi-module codebase.
## Placement `@DisabledInAotMode` can be applied at: - **Type level (test class)** — since **Spring Framework 6.1**. Disables the entire class in AOT mode and excludes its context from build-time AOT generation. This is the typical usage because AOT-incompatibility usually stems from the **context configuration** (e.g., the class declares `@MockitoBean`), which is shared by all methods. - **Method level (individual @Test)** — since **Spring Framework 6.2**. Lets you disable a single incompatible method while keeping the rest of the class in the AOT run. - **As a meta-annotation** — you can compose your own annotation that carries `@DisabledInAotMode`. ## Version timeline - **6.1**: annotation introduced; class-level only. - **6.2**: adds **method-level** support and an optional **`String value()`** attribute for a reason message (surfaced in the test skip report, aiding diagnosis). ## Choosing class vs method - If the incompatibility is in the **context** (a mock bean the whole class shares), annotate the **class** — the whole context is un-AOT-able anyway. - If most methods are fine and only one does something context-mutating, annotate that **method**. This maximizes native-image coverage. ## Gotchas - The `value()` reason is documentation/reporting only — it does not change behavior. - On older Spring (6.1) method-level placement isn't available; you must move the incompatible logic into its own class or disable the whole class. - Because AOT-incompatibility is usually context-scoped, method-level use is less common than it sounds — if the class instantiates a mock-bean context, all its methods share that context. - Don't confuse the reason string with JUnit's `@Disabled("reason")`; they're separate annotations even though the reason concept looks similar.
- You are on Spring 6.1 and only one method in a class is AOT-incompatible. What are your options?Method-level support arrived in 6.2, so on 6.1 you either annotate the whole class (losing AOT coverage for its other methods) or extract the incompatible method into its own class and annotate that.
saying these in an interview costs you the question
- Claiming method-level support existed from the start in 6.1
- Thinking the reason string changes runtime behavior
- Assuming it can only ever go on a class