Skip to main content

Mock Full 06 — Spring Professional (60 Questions)

Exam style: Spring Professional Develop (2V0-72.22) — full 60-question mixed-topic mock.

Time limit: ~130 minutes (about 2 minutes per question).

Instructions:

  1. Pick an option for each question, then use Check answer to reveal the explanation and score.
  2. Use Back and Next to move through the set; you can change your selection until you check.
  3. For every miss, read the explanation and add one memory sentence before moving on.

Topic coverage:

  • Q1–10: Spring Core & DI
  • Q11–18: Configuration, Profiles & Scopes
  • Q19–28: Spring Boot, Auto-Configuration & Actuator
  • Q29–36: Spring MVC, REST & Validation
  • Q37–44: Data Access, JPA & Transactions
  • Q45–50: Spring Security
  • Q51–56: Testing
  • Q57–60: AOP, Events, Async & Observability

Question 1

A fintech team bootstraps a CLI batch job with ClassPathXmlApplicationContext while the web tier uses AnnotationConfigServletWebServerApplicationContext.

Which statement about ApplicationContext implementations and their capabilities is correct?

  • A) FileSystemXmlApplicationContext loads definitions from the filesystem and still supports the full ApplicationContext feature set
  • B) All ApplicationContext types eagerly create every prototype bean during context refresh
  • C) Only web-aware contexts can publish ApplicationEvent instances to ApplicationListener beans
  • D) GenericApplicationContext can register @Configuration classes but cannot refresh more than once
Answer & explanation

Correct answer: A

FileSystemXmlApplicationContext is a concrete ApplicationContext that loads bean definitions from the filesystem (not classpath) and inherits enterprise features such as event publication, internationalization, and automatic BeanPostProcessor registration. Prototype beans are created on demand, not eagerly at refresh. Non-web contexts like AnnotationConfigApplicationContext can publish events. GenericApplicationContext supports repeated refresh in some setups, but the filesystem context distinction is the exam-relevant point here.

Why the other options are wrong:

  • B) Prototype-scoped beans are lazily instantiated on first getBean or injection, not at refresh.
  • C) AnnotationConfigApplicationContext and other non-web contexts publish ApplicationEvents normally.
  • D) GenericApplicationContext is often used for programmatic registration; refresh semantics vary and this is not the distinguishing filesystem capability.

Memory sentence: "Filesystem XML context = ApplicationContext loading definitions from disk, not classpath."

Study: Book chapter

Question 2

LedgerService is a singleton component with one constructor and one setter both marked @Autowired. How does Spring inject dependencies?

@Service
public class LedgerService {
private final AuditPort auditPort;

@Autowired
public LedgerService(AuditPort auditPort) {
this.auditPort = auditPort;
}

@Autowired
public void setMetrics(MetricsClient metrics) {
this.metrics = metrics;
}
private MetricsClient metrics;
}
  • A) Spring uses constructor injection for AuditPort and setter injection for MetricsClient
  • B) Constructor injection runs first; the setter is ignored because only one injection style is allowed
  • C) Spring fails startup: mixing constructor and setter @Autowired on the same class is illegal
  • D) Spring injects both dependencies through the constructor by autowiring the setter parameters
Answer & explanation

Correct answer: A

Spring supports multiple injection mechanisms on the same class. Required dependencies via constructor are satisfied at instantiation time; @Autowired setters run afterward during dependency injection. This mixed style is valid, though constructor-only is preferred for required immutable fields.

Why the other options are wrong:

  • B) Setter @Autowired is not ignored; it is processed after the object is constructed.
  • C) Mixing constructor and setter injection is fully supported.
  • D) Setters are not folded into constructor autowiring; they are separate injection points.

Memory sentence: "Constructor wires first, then @Autowired setters — both can coexist on one bean."

Study: Book chapter

Question 3

InventoryService depends on CacheProvider. Two beans exist: redisCacheProvider (@Primary) and caffeineCacheProvider (@Qualifier("local")).

The constructor parameter is annotated @Qualifier("local") CacheProvider cache. Which bean is injected?

  • A) caffeineCacheProvider because @Qualifier on the injection point overrides @Primary
  • B) @Primary redisCacheProvider because @Primary always wins over @Qualifier
  • C) Startup fails with NoUniqueBeanDefinitionException
  • D) A new anonymous CacheProvider proxy combining both implementations
Answer & explanation

Correct answer: A

@Qualifier on the injection point selects a specific bean by name or custom qualifier value. It takes precedence over @Primary for that injection site. @Primary only applies when no qualifier disambiguates the dependency.

Why the other options are wrong:

  • B) @Primary is the default when ambiguous; explicit @Qualifier overrides it.
  • C) The qualifier resolves ambiguity; startup succeeds.
  • D) Spring does not merge multiple beans into a composite unless a custom factory does so.

Memory sentence: "Injection-point @Qualifier beats @Primary for that dependency."

Study: Book chapter

Question 4

Formatter is prototype-scoped. ReportExporter is singleton. What does ObjectProvider<Formatter> give the singleton?

@Component
public class ReportExporter {
@Autowired
private ObjectProvider<Formatter> formatterProvider;
}
  • A) A lazy handle to obtain a new or existing Formatter instance on demand without eager prototype creation at singleton startup
  • B) A compile-time error because ObjectProvider cannot wrap prototype beans
  • C) The same prototype instance cached forever inside the singleton
  • D) Automatic @Lookup method semantics without declaring @Lookup
Answer & explanation

Correct answer: A

ObjectProvider is a factory abstraction that defers dependency resolution. For prototype beans injected into singletons, it avoids early instantiation and lets code call getObject() when a fresh instance is needed. It is the idiomatic alternative to @Lookup for optional or scoped dependencies.

Why the other options are wrong:

  • B) ObjectProvider is designed precisely for optional, multiple, or scoped bean retrieval.
  • C) Each getObject() for a prototype yields a distinct instance unless scoped otherwise.
  • D) ObjectProvider is related but not identical to @Lookup; it is an injected provider handle.

Memory sentence: "ObjectProvider = deferred factory for scoped, optional, or multiple candidates."

Study: Book chapter

Question 5

A @Bean method returns a new DataSource each call. Another @Configuration class @Import`s the first. How many DataSource instances exist in the container?

@Configuration
public class InfraConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}

@Configuration
@Import(InfraConfig.class)
public class AppConfig { }
  • A) One singleton DataSource because @Bean methods in @Configuration are proxied and intercepted
  • B) Two instances because @Import always duplicates beans
  • C) Zero unless a @Component explicitly @Autowired DataSource
  • D) One per injection point, similar to prototype scope
Answer & explanation

Correct answer: A

@Configuration classes are full-mode proxied so @Bean method interceptions return the same singleton bean from the container when the method is called again within configuration class processing. @Import registers the imported configuration without duplicating singleton semantics.

Why the other options are wrong:

  • B) @Import brings in definitions; it does not duplicate singleton beans.
  • C) @Bean registers a bean definition regardless of injection demand.
  • D) Default @Bean scope is singleton (one per bean name), not per injection point.

Memory sentence: "Full @Configuration proxies @Bean methods so repeated calls return the same singleton."

Study: Book chapter

Question 6

A developer adds @Component to an abstract BaseProcessor and @Component to concrete CsvProcessor extending it.

With default component scanning, what is registered?

  • A) Only CsvProcessor; abstract @Component classes are not instantiated as beans
  • B) Both BaseProcessor and CsvProcessor beans
  • C) Neither, because inheritance breaks stereotype detection
  • D) A single bean using the superclass name baseProcessor
Answer & explanation

Correct answer: A

Abstract classes annotated with @Component are detected as candidates but cannot be instantiated. Concrete subclasses like CsvProcessor are registered as beans. The abstract parent is not a standalone bean instance in the container.

Why the other options are wrong:

  • B) Abstract classes cannot be instantiated; Spring skips creating a bean for the abstract type.
  • C) Inheritance does not break scanning; concrete subclasses are still picked up.
  • D) No bean is created for the abstract class itself.

Memory sentence: "Abstract @Component types are not instantiated; concrete subclasses become beans."

Study: Book chapter

Question 7

No @Primary or @Qualifier is present. What happens at startup?

public interface PaymentPort { }

@Component("legacy")
public class LegacyPaymentAdapter implements PaymentPort { }

@Component("modern")
public class ModernPaymentAdapter implements PaymentPort { }

@Service
public class CheckoutService {
public CheckoutService(PaymentPort port) { }
}
  • A) Startup fails with NoUniqueBeanDefinitionException for PaymentPort
  • B) Spring injects legacy because @Component("legacy") sorts first alphabetically
  • C) Spring injects modern because it is the default implementation by convention
  • D) Spring creates a JDK dynamic proxy implementing PaymentPort that delegates to both adapters
Answer & explanation

Correct answer: A

When multiple beans match a single injection point type and no @Qualifier, @Primary, or @Resource name match resolves the ambiguity, Spring throws NoUniqueBeanDefinitionException during startup. Alphabetical bean names or conventions do not apply.

Why the other options are wrong:

  • B) Bean name ordering is not a disambiguation rule.
  • C) There is no "default implementation" convention without @Primary.
  • D) Spring does not auto-compose multiple beans into one proxy unless configured.

Memory sentence: "Two beans, one type, no qualifier → NoUniqueBeanDefinitionException."

Study: Book chapter

Question 8

Which statement about the Spring IoC container and dependency graphs is correct?

  • A) The container can resolve some circular dependencies for singletons using early exposed references or setter injection
  • B) Circular dependencies between singleton setter injections always fail unconditionally in every Spring version
  • C) Prototype beans participating in cycles are always resolved using constructor injection retries
  • D) Circular dependencies are detected only at runtime on first getBean, never during context refresh
Answer & explanation

Correct answer: A

Spring can break certain singleton circular dependencies by exposing a partially initialized bean early (singleton factory) or through setter/field injection where the object exists before dependencies are set. Constructor-only cycles among singletons typically fail. Prototype cycles are problematic because a new instance is needed each time.

Why the other options are wrong:

  • B) Setter/field cycles among singletons can succeed; constructor-only cycles usually fail.
  • C) Prototype involvement in cycles commonly fails; constructor retries are not used.
  • D) Many circular dependency failures surface during context refresh, not lazily at first use.

Memory sentence: "Singleton setter cycles may work; constructor-only singleton cycles usually fail."

Study: Book chapter

Question 9

Assuming lite @Configuration mode (no CGLIB proxy), how many XmlParser instances are created when jsonParser() is first requested?

@Configuration
public class ParserConfig {
@Bean
public JsonParser jsonParser() {
return new JsonParser(xmlParser());
}

@Bean
public XmlParser xmlParser() {
return new XmlParser();
}
}
  • A) Two XmlParser instances: one container-managed bean and one created inside jsonParser()
  • B) One shared XmlParser bean used by both @Bean methods
  • C) Zero; lite mode disables @Bean registration
  • D) One XmlParser per application refresh only if @Scope("prototype") is added
Answer & explanation

Correct answer: A

In lite @Configuration (or @Bean methods on non-@Configuration classes), @Bean methods are plain method calls. Calling xmlParser() inside jsonParser() creates a separate object not managed as the shared singleton bean. Full @Configuration proxy mode intercepts calls to return the container bean.

Why the other options are wrong:

  • B) Without proxy interception, direct method calls bypass the container singleton.
  • C) Lite mode still registers @Bean definitions; it only skips configuration class subclass proxying.
  • D) Scope defaults to singleton per bean name, but the direct call still creates an extra instance.

Memory sentence: "Lite @Configuration: calling @Bean methods directly can create extra instances."

Study: Book chapter

Question 10

A team removes all Spring annotations and manually calls new ServiceA(new ServiceB()) in main().

Which problem that Spring DI solves reappears first in integration tests?

  • A) Inability to swap collaborators with test doubles without changing production construction code
  • B) Loss of internationalization support in the IoC container
  • C) Missing automatic Actuator endpoints
  • D) Disabled @Transactional processing on main()
Answer & explanation

Correct answer: A

Manual construction tightly couples classes to concrete implementations, making it hard to substitute mocks or stubs in tests. Spring DI externalizes object graph assembly so tests can replace beans via @MockBean, @TestConfiguration, or alternate contexts.

Why the other options are wrong:

  • B) i18n is unrelated to the immediate testing pain of manual new wiring.
  • C) Actuator is a Spring Boot concern, not the first DI regression.
  • D) @Transactional requires Spring management; it is not the "first" DI problem described.

Memory sentence: "Manual new() couples code to concrete types and blocks easy test doubles."

Study: Book chapter

Question 11

shipping.max-weight-kg=30 and shipping.sla=PT2H are in application.yml. ShippingProps is a @ConfigurationProperties record without @Component. What is required for binding to work?

@ConfigurationProperties(prefix = "shipping")
public record ShippingProps(int maxWeightKg, Duration sla) { }

@RestController
public class QuoteController {
public QuoteController(ShippingProps props) { }
}
  • A) Register ShippingProps via @EnableConfigurationProperties(ShippingProps.class) or @ConfigurationPropertiesScan
  • B) Add @Value on each record component; @ConfigurationProperties does not bind records
  • C) Records cannot be beans; convert to a class with setters
  • D) Binding works automatically for any record on the classpath without registration
Answer & explanation

Correct answer: A

@ConfigurationProperties types must be registered as beans through @EnableConfigurationProperties, @ConfigurationPropertiesScan, or stereotype registration. Once registered, Boot binds kebab-case properties to record components. @Value is per-field and not the ConfigurationProperties model.

Why the other options are wrong:

  • B) @ConfigurationProperties binds immutable records when registered; @Value is unnecessary.
  • C) Records are supported as @ConfigurationProperties beans in modern Spring Boot.
  • D) Registration is required; classpath presence alone is insufficient.

Memory sentence: "ConfigurationProperties types need explicit enablement/scan — records included."

Study: Book chapter

Question 12

A bean is annotated @Profile("!integration & cloud") and active profiles are integration,cloud.

Is the bean registered?

  • A) No, because the expression requires a profile that is not integration AND includes cloud; with both active the negated clause fails
  • B) Yes, because negated profiles cancel active ones
  • C) Yes, profile expressions are ignored when multiple profiles are active
  • D) Only in the default profile
Answer & explanation

Correct answer: A

@Profile supports expressions. "!integration & cloud" means not integration AND cloud must hold. With active profiles integration and cloud, the !integration part is false, so the whole expression is false and the bean is not registered.

Why the other options are wrong:

  • B) Negation does not "cancel" an active profile in an AND expression; all parts must match.
  • C) Profile expressions are evaluated with active profile sets.
  • D) Default profile is unrelated to explicit active profiles integration and cloud.

Memory sentence: "!integration & cloud fails when integration is among active profiles."

Study: Book chapter

Question 13

TraceService is singleton. RequestIdHolder is request-scoped with TARGET_CLASS proxy. What does TraceService actually hold?

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestIdHolder {
private String requestId;
public void setRequestId(String id) { this.requestId = id; }
public String getRequestId() { return requestId; }
}

@Service
public class TraceService {
private final RequestIdHolder holder;
public TraceService(RequestIdHolder holder) { this.holder = holder; }
}
  • A) A CGLIB proxy delegating each method call to the current request-scoped bean
  • B) A direct request-scoped instance shared across all HTTP requests
  • C) A new RequestIdHolder per TraceService method invocation automatically
  • D) Compile failure because singletons cannot depend on request-scoped beans
Answer & explanation

Correct answer: A

Injecting a shorter-lived scope into a singleton requires a scoped proxy. TARGET_CLASS creates a CGLIB proxy that looks up the real request bean per thread/request when methods are invoked, preserving correct lifecycle semantics.

Why the other options are wrong:

  • B) A direct instance would be one per singleton, breaking request isolation.
  • C) Proxies delegate per call to the scoped target, not per TraceService method automatically.
  • D) This pattern is valid and common with scoped proxies.

Memory sentence: "Request bean into singleton → scoped CGLIB proxy delegates per request."

Study: Book chapter

Question 14

A @Bean method declares @Scope("prototype") and is called from another @Bean method in the same full @Configuration class. How many prototype instances does the container manage for calls through the proxy?

  • A) Each intercepted @Bean method call through the proxy returns the container-managed prototype instance for that bean name, but internal direct calls may bypass the proxy
  • B) Always one because @Configuration proxies collapse prototype calls
  • C) Prototype scope is upgraded to singleton inside @Configuration classes
  • D) Zero; prototypes must be @Component types only
Answer & explanation

Correct answer: A

Full @Configuration proxies intercept @Bean method calls from other @Bean methods and route through the container, so prototype beans still create a new instance per getBean/intercepted call. The trap is direct Java calls on this (lite mode) bypassing interception.

Why the other options are wrong:

  • B) Intercepted prototype @Bean calls still produce distinct instances per invocation.
  • C) Scope is not upgraded; proxy ensures container semantics.
  • D) @Bean methods can declare prototype scope.

Memory sentence: "Full @Configuration intercepts @Bean calls — prototype still new per intercepted call."

Study: Book chapter

Question 15

In a running Spring Boot app, when are these callbacks invoked relative to @PreDestroy on another bean?

@Component
public class WarmupRunner implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() { /* connect pool */ }
@Override
public void destroy() { /* close pool */ }
}
  • A) afterPropertiesSet runs after all beans exist; DisposableBean.destroy runs during context shutdown in reverse dependency order broadly
  • B) Both run before any constructor completes
  • C) destroy runs before afterPropertiesSet on refresh
  • D) InitializingBean replaces @PostConstruct and prevents @PreDestroy from running
Answer & explanation

Correct answer: A

InitializingBean.afterPropertiesSet executes after dependency injection for that bean. DisposableBean.destroy and @PreDestroy methods run on context shutdown, generally respecting dependency order in reverse. They are complementary lifecycle hooks, not mutually exclusive.

Why the other options are wrong:

  • B) Initialization callbacks run after construction and injection.
  • C) destroy is a shutdown hook, not part of refresh initialization ordering before afterPropertiesSet.
  • D) @PreDestroy still runs; interfaces do not disable annotation-based lifecycle.

Memory sentence: "afterPropertiesSet after injection; destroy/@PreDestroy on shutdown."

Study: Book chapter

Question 16

application.properties sets spring.profiles.active=dev and spring.config.activate.on-profile=dev on a nested document in application-dev.yml.

Which is true about property loading order?

  • A) application.properties always overrides profile-specific YAML regardless of order
  • B) Profile-specific files load when the profile is active; later sources in Spring Boot property precedence can override earlier ones
  • C) spring.config.activate.on-profile replaces spring.profiles.active entirely
  • D) YAML and properties files cannot coexist in the same Boot app
Answer & explanation

Correct answer: B

Spring Boot loads profile-specific documents when profiles are active. Property precedence follows ordered property sources: command line, OS env, profile-specific files, application.properties, defaults, etc. Later higher-precedence sources override earlier values.

Why the other options are wrong:

  • A) Precedence is not "properties always win"; it depends on source order and rules.
  • C) activate.on-profile gates documents; it does not replace profile activation mechanism.
  • D) Boot supports both YAML and properties together.

Memory sentence: "Active profile files load conditionally; precedence decides overrides."

Study: Book chapter

Question 17

Which technology resolves this injection?

@Value("#{systemProperties['user.timezone']}")
private String timezone;
  • A) PropertySourcesPlaceholderConfigurer only
  • B) Spring Expression Language (SpEL) embedded in @Value
  • C) JNDI lookup in the application server
  • D) Automatic @ConfigurationProperties binding
Answer & explanation

Correct answer: B

The #{expression} syntax in @Value denotes SpEL evaluation. systemProperties is a SpEL variable exposing JVM system properties. Plain ${property} would be property placeholder resolution without SpEL.

Why the other options are wrong:

  • A) PlaceholderConfigurer handles ${property}; #{expression} is SpEL via StandardBeanExpressionResolver.
  • C) No JNDI is involved in this expression.
  • D) @ConfigurationProperties is unrelated to inline SpEL @Value.

Memory sentence: "@Value #{expression} = SpEL; ${property} = property placeholder."

Study: Book chapter

Question 18

@Bean public static BeanFactoryPostProcessor registrar() { return beanFactory -> { }; } must be static. Why?

  • A) Static methods produce prototype beans automatically
  • B) Static @Bean methods are invoked early during context parsing before regular @Configuration instance beans are created, allowing BeanFactoryPostProcessor registration
  • C) Non-static BFPP @Bean methods create circular dependency with the configuration instance
  • D) Only static methods can use @Profile on @Bean methods
Answer & explanation

Correct answer: B

BeanFactoryPostProcessor beans must be registered before bean definitions are fully processed. Static @Bean methods on @Configuration classes are called without instantiating the @Configuration object, ensuring early registration. Non-static BFPP @Bean methods can work but may be deferred, causing ordering issues.

Why the other options are wrong:

  • A) Static does not imply prototype scope.
  • C) The issue is lifecycle ordering, not a generic circular dependency rule.
  • D) @Profile is not limited to static @Bean methods.

Memory sentence: "Static @Bean BFPP = early registration before configuration instance exists."

Study: Book chapter

Question 19

A library ships META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports listing com.acme.MetricsAutoConfiguration.

How does Spring Boot 3 load this auto-configuration?

  • A) Through spring.factories EnableAutoConfiguration key only
  • B) Through the AutoConfiguration.imports mechanism processed by AutoConfigurationImportSelector
  • C) Via @Import on @SpringBootApplication directly reading the file at runtime
  • D) Only if the user adds @Import(MetricsAutoConfiguration.class) manually
Answer & explanation

Correct answer: B

Spring Boot 2.7+ and Boot 3 use META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports for registering auto-configuration classes. AutoConfigurationImportSelector loads them when @EnableAutoConfiguration (meta on @SpringBootApplication) is present.

Why the other options are wrong:

  • A) spring.factories EnableAutoConfiguration is legacy; imports file is the Boot 3 path.
  • C) @SpringBootApplication enables auto-config through selectors, not direct file parsing in user code.
  • D) Library auto-config should load automatically without manual @Import.

Memory sentence: "Boot 3 auto-config classes live in AutoConfiguration.imports."

Study: Book chapter

Question 20

Jedis is on the classpath and the application defines its own RedisTemplate bean. What happens?

@ConditionalOnClass(name = "redis.clients.jedis.Jedis")
@ConditionalOnMissingBean(RedisTemplate.class)
public class RedisAutoConfiguration {
@Bean RedisTemplate<String, String> redisTemplate() { return new RedisTemplate<>(); }
}
  • A) Both RedisTemplate beans register and @Primary is required
  • B) RedisAutoConfiguration backs off because @ConditionalOnMissingBean finds an existing RedisTemplate
  • C) Auto-configuration overrides the user bean because it loads first
  • D) Application fails because duplicate bean names are illegal
Answer & explanation

Correct answer: B

@ConditionalOnMissingBean prevents auto-config from registering a bean when the user already defined one of that type. This is the back-off pattern preserving user overrides. @ConditionalOnClass ensures Redis support is only considered when Jedis is present.

Why the other options are wrong:

  • A) Back-off avoids duplicate beans; no @Primary battle occurs.
  • C) User beans generally take precedence; auto-config is conditional.
  • D) Back-off prevents duplicate registration failure.

Memory sentence: "OnMissingBean = auto-config steps aside when user bean exists."

Study: Book chapter

Question 21

management.endpoints.web.exposure.include=health,info,metrics and management.endpoint.health.show-details=when_authorized. An unauthenticated GET /actuator/health is issued. What is typical?

  • A) Full component details for disk space and database always appear
  • B) Aggregated health status appears; detailed components may be hidden unless authorized per configuration
  • C) 404 because health must be enabled with management.endpoint.health.enabled=true separately in all versions
  • D) Response is always empty JSON {}
Answer & explanation

Correct answer: B

Exposing health via web exposure includes the endpoint. show-details=when_authorized suppresses detailed components for unauthenticated callers while still returning top-level status (UP/DOWN). Authorization rules depend on Spring Security when present.

Why the other options are wrong:

  • A) Details are restricted by show-details policy for anonymous users.
  • C) Included in exposure list enables web access; separate enabled flag defaults true.
  • D) Health returns status information, not empty body.

Memory sentence: "show-details=when_authorized hides component details from anonymous callers."

Study: Book chapter

Question 22

Which annotations are meta-annotated on @SpringBootApplication by default?

@SpringBootApplication
public class ShopApplication {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
}
  • A) @EnableWebMvc, @EnableJpaRepositories, and @EnableScheduling
  • B) @EnableAutoConfiguration, @ComponentScan, and @Configuration
  • C) @SpringBootConfiguration only
  • D) @ImportAutoConfiguration and @EnableActuator
Answer & explanation

Correct answer: B

@SpringBootApplication composes @SpringBootConfiguration (specialized @Configuration), @EnableAutoConfiguration, and @ComponentScan. It does not automatically enable @EnableWebMvc, JPA repositories, scheduling, or Actuator.

Why the other options are wrong:

  • A) Those capabilities come from starters and additional annotations or auto-config, not @SpringBootApplication itself.
  • C) It includes more than @SpringBootConfiguration.
  • D) No @EnableActuator meta-annotation exists on @SpringBootApplication.

Memory sentence: "@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan."

Study: Book chapter

Question 23

spring.main.lazy-initialization=true is set for a large monolith during development.

What is the most significant behavioral change?

  • A) All @Bean methods become prototype-scoped
  • B) Singleton beans are created when first needed rather than eagerly at context refresh (with exceptions such as infrastructure beans)
  • C) Actuator endpoints are disabled automatically
  • D) @Transactional stops working on lazy beans
Answer & explanation

Correct answer: B

Lazy initialization defers singleton bean creation until first dependency injection or explicit getBean, speeding startup in development. Infrastructure beans and some Boot internals may still initialize eagerly. @Transactional and Actuator are not globally disabled.

Why the other options are wrong:

  • A) Lazy initialization changes timing, not scope.
  • C) Actuator remains available if on classpath and configured.
  • D) Transaction management applies when beans are invoked, not at creation time only.

Memory sentence: "lazy-initialization=true defers singleton creation until first use."

Study: Book chapter

Question 24

A custom HealthIndicator returns Health.down().withDetail("queue", "stalled").build(). The diskSpaceHealthIndicator reports UP. What is the composite /actuator/health status?

  • A) UP because majority of indicators are UP
  • B) DOWN because any contributing HealthIndicator reporting DOWN makes aggregate status DOWN
  • C) UNKNOWN always when details are present
  • D) OUT_OF_SERVICE only if management.health.defaults.enabled=false
Answer & explanation

Correct answer: B

Spring Boot HealthContributorRegistry aggregates contributors. If any participant is DOWN, the overall health status becomes DOWN unless configured otherwise. Details are attached per contributor but do not change the aggregation rule.

Why the other options are wrong:

  • A) Health aggregation is not democratic majority vote.
  • C) Details do not force UNKNOWN.
  • D) OUT_OF_SERVICE is a distinct status, not tied to that property in this scenario.

Memory sentence: "Any DOWN contributor pulls composite /actuator/health to DOWN."

Study: Book chapter

Question 25

When does ApplicationRunner.run execute relative to the context being ready?

public class AuditApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
// seed reference data
}
}
  • A) Before any bean is created
  • B) After the ApplicationContext is fully refreshed but before the application signals readiness (part of startup callbacks)
  • C) Only on SIGTERM shutdown
  • D) Only when @PostConstruct on the same class completes first if both exist
Answer & explanation

Correct answer: B

ApplicationRunner and CommandLineRunner beans execute after context refresh during application startup, ordered with @Order. They run after beans are initialized, suitable for startup tasks using ApplicationArguments.

Why the other options are wrong:

  • A) Beans must exist; runners are beans invoked after refresh.
  • C) Runners are startup hooks, not shutdown hooks.
  • D) @PostConstruct on the same bean runs before run(); both can exist with distinct timing.

Memory sentence: "ApplicationRunner runs after context refresh during startup."

Study: Book chapter

Question 26

spring-boot-starter-web brings spring-boot-starter-tomcat transitively. The team excludes Tomcat and adds spring-boot-starter-jetty. Which remains true?

  • A) @SpringBootApplication disables servlet auto-configuration automatically
  • B) ServletWebServerFactory auto-configuration selects Jetty when Tomcat is absent and Jetty is on classpath
  • C) The app becomes a non-web Reactive application
  • D) DispatcherServlet is no longer registered
Answer & explanation

Correct answer: B

Spring Boot servlet web auto-configuration is conditional on available embedded server implementations. Excluding Tomcat and adding Jetty causes JettyServletWebServerFactory auto-config to back off Tomcat and use Jetty. It remains a servlet stack with DispatcherServlet.

Why the other options are wrong:

  • A) Web auto-config remains for servlet stacks with an embedded server present.
  • C) Jetty supports servlet MVC; this is not a switch to WebFlux by itself.
  • D) DispatcherServlet is still part of spring-boot-starter-web.

Memory sentence: "Swap embedded server via starter exclusions; servlet MVC stays."

Study: Book chapter

Question 27

Developer runs java -jar app.jar --debug and sets logging.level.org.springframework.boot.autoconfigure=DEBUG.

What additional startup artifact helps diagnose auto-configuration decisions?

  • A) A heap dump written to /tmp
  • B) Auto-configuration report showing matched and negative @Conditional evaluations
  • C) Automatic rollback of all @Bean definitions
  • D) Disabling of @ConditionalOnProperty checks
Answer & explanation

Correct answer: B

Boot can log an auto-configuration report at DEBUG/TRACE for org.springframework.boot.autoconfigure, listing which configurations matched, did not match, and excluded. --debug also triggers a condition evaluation report in the console.

Why the other options are wrong:

  • A) Debug does not produce heap dumps.
  • C) Reports are diagnostic only; they do not rollback beans.
  • D) Condition evaluation still runs; logging reveals outcomes.

Memory sentence: "DEBUG auto-config package → condition match/negative report at startup."

Study: Book chapter

Question 28

micrometer-registry-prometheus is on the classpath and management.endpoints.web.exposure.include=prometheus. Where are metrics exposed?

  • A) Only via JMX unless explicitly disabled
  • B) At /actuator/prometheus as a scrape endpoint in addition to general metrics infrastructure
  • C) Inside /actuator/health only
  • D) Prometheus format requires replacing Actuator with a custom controller always
Answer & explanation

Correct answer: B

Adding micrometer-registry-prometheus registers a PrometheusMeterRegistry and, when exposed, serves metrics at /actuator/prometheus for scraping. General metrics remain available through /actuator/metrics.

Why the other options are wrong:

  • A) Web exposure serves HTTP scrape endpoint, not JMX-only.
  • C) Health and prometheus endpoints are separate.
  • D) Boot provides integrated Actuator support without mandatory custom controller.

Memory sentence: "Prometheus registry + exposure → scrape at /actuator/prometheus."

Study: Book chapter

Question 29

A GET request arrives for /api/orders. Which mapping handler is selected?

@RestController
@RequestMapping("/api/orders")
public class OrderController {
@GetMapping("/{id}")
public OrderDto get(@PathVariable Long id) { return service.find(id); }

@GetMapping("")
public List<OrderDto> list() { return service.findAll(); }
}
  • A) get(@PathVariable Long id) because path variables take precedence
  • B) list() because the empty path segment matches the collection endpoint
  • C) Both match and Spring returns 500 Ambiguous mapping
  • D) Neither; /api/orders requires a trailing slash mapping only
Answer & explanation

Correct answer: B

GET /api/orders matches @GetMapping("") on the class-level /api/orders controller, resolving to list(). GET /api/orders/42 matches @GetMapping("/{id}"). Spring MVC distinguishes explicit path patterns; the collection URI without an id segment maps to the empty sub-path.

Why the other options are wrong:

  • A) /{id} requires an additional path segment; bare /api/orders does not supply it.
  • C) Patterns are not ambiguous for these two distinct paths.
  • D) Trailing slash behavior is configurable; the mapping is valid without extra slash rules.

Memory sentence: "/api/orders maps to "" sub-path; /api/orders/{id} maps to item endpoint."

Study: Book chapter

Question 30

A client sends POST /api/users with Content-Type: application/json and a malformed body.

Which exception type is typically processed before reaching a @ControllerAdvice method for business errors?

  • A) AccessDeniedException from Spring Security only
  • B) HttpMessageNotReadableException during @RequestBody deserialization
  • C) TransactionSystemException from JPA
  • D) BeanCurrentlyInCreationException
Answer & explanation

Correct answer: B

Malformed JSON or type mismatches during HttpMessageConverter reading trigger HttpMessageNotReadableException in the MVC layer before controller logic runs. @ControllerAdvice can map it to 400 Bad Request.

Why the other options are wrong:

  • A) AccessDeniedException relates to authorization failures, not JSON parsing.
  • C) TransactionSystemException occurs in transactional persistence layer.
  • D) BeanCurrentlyInCreationException is a context initialization issue.

Memory sentence: "Bad JSON on @RequestBody → HttpMessageNotReadableException → typically 400."

Study: Book chapter

Question 31

Validation fails on email. What happens by default if no @ControllerAdvice handles MethodArgumentNotValidException?

public record CreateUserRequest(
@NotBlank String email,
@Min(18) int age
) { }

@PostMapping("/users")
public ResponseEntity<Void> create(@Valid @RequestBody CreateUserRequest req) { }
  • A) 200 OK with empty body
  • B) 500 Internal Server Error
  • C) 400 Bad Request with default MVC error handling (or ProblemDetail in Boot 3 defaults depending on configuration)
  • D) Silently ignored; req arrives with null email
Answer & explanation

Correct answer: C

@Valid on @RequestBody triggers Bean Validation. Constraint violations raise MethodArgumentNotValidException. Without custom handling, Spring MVC/Boot default error handling typically responds with 400 and error details.

Why the other options are wrong:

  • A) Validation failure prevents normal controller success path.
  • B) Default handling maps client validation errors to 4xx, not 500.
  • D) Invalid requests do not silently pass validation.

Memory sentence: "@Valid failure on @RequestBody → MethodArgumentNotValidException → 400 class response."

Study: Book chapter

Question 32

Which component is responsible for selecting the correct @RequestMapping handler method based on URL, HTTP method, and content type?

  • A) HandlerAdapter exclusively
  • B) ViewResolver
  • C) HandlerMapping locates the handler; HandlerAdapter invokes it
  • D) HttpMessageConverter
Answer & explanation

Correct answer: C

DispatcherServlet consults HandlerMapping implementations to resolve a handler (controller method). HandlerAdapter then invokes that handler. ViewResolver resolves views; HttpMessageConverter reads/writes bodies.

Why the other options are wrong:

  • A) HandlerAdapter invokes handlers but does not perform mapping selection.
  • B) ViewResolver maps logical view names to View implementations.
  • D) HttpMessageConverter handles message conversion, not handler selection.

Memory sentence: "HandlerMapping finds the handler; HandlerAdapter executes it."

Study: Book chapter

Question 33

Which HttpMessageConverter likely writes the response body?

@GetMapping("/report")
public ResponseEntity<byte[]> download() {
byte[] pdf = generator.render();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=report.pdf")
.contentType(MediaType.APPLICATION_PDF)
.body(pdf);
}
  • A) MappingJackson2HttpMessageConverter
  • B) StringHttpMessageConverter
  • C) ByteArrayHttpMessageConverter or ResourceHttpMessageConverter depending on type
  • D) FormHttpMessageConverter
Answer & explanation

Correct answer: C

byte[] responses are handled by ByteArrayHttpMessageConverter (or similar) when content type is application/pdf. Jackson is for JSON object graphs, not raw binary PDF bytes.

Why the other options are wrong:

  • A) Jackson converts object graphs to JSON, not arbitrary PDF bytes.
  • B) String converter handles String bodies, not byte arrays with PDF content type.
  • D) Form converter handles form data, not binary downloads.

Memory sentence: "byte[] + MediaType → ByteArrayHttpMessageConverter, not Jackson."

Study: Book chapter

Question 34

A controller method returns ResponseEntity<ProblemDetail> with status 404 from a @RestControllerAdvice.

What is true about @RestControllerAdvice compared to @ControllerAdvice?

  • A) @RestControllerAdvice only works on @Controller classes, not @RestController
  • B) @RestControllerAdvice disables @ExceptionHandler completely
  • C) @RestControllerAdvice applies @ResponseBody semantics to @ExceptionHandler methods, serializing return values directly
  • D) @ControllerAdvice cannot handle REST exceptions
Answer & explanation

Correct answer: C

@RestControllerAdvice is a composed annotation adding @ResponseBody behavior to exception handler methods, so return values are written via HttpMessageConverters—ideal for REST error payloads like ProblemDetail.

Why the other options are wrong:

  • A) It targets REST-style exception handling across controllers including @RestController.
  • B) It specializes @ExceptionHandler for direct message conversion.
  • D) @ControllerAdvice can handle exceptions; @RestControllerAdvice adds response body semantics.

Memory sentence: "@RestControllerAdvice = @ControllerAdvice + @ResponseBody on handlers."

Study: Book chapter

Question 35

Client sends PUT /items/5 with JSON body where id field is 9. What is typical for id used in service.update?

@PutMapping("/items/{id}")
public ItemDto update(@PathVariable Long id, @RequestBody ItemDto dto) {
return service.update(id, dto);
}
  • A) Always 9 from the body; path variable is ignored
  • B) 400 error automatically because path and body ids differ
  • C) Path variable 5 is passed as method parameter id; body field id may differ unless synchronized manually
  • D) Spring merges them to 14
Answer & explanation

Correct answer: C

Path variables and request body fields bind independently. The @PathVariable Long id comes from the URL (/items/5 → 5). The body id field populates dto.id separately. Business logic must reconcile mismatches if required.

Why the other options are wrong:

  • A) Path variable parameter binding is independent of body fields.
  • B) No automatic error unless validation or custom checks enforce equality.
  • D) Spring does not arithmetically merge identifiers.

Memory sentence: "@PathVariable and @RequestBody fields bind separately — reconcile in code."

Study: Book chapter

Question 36

@CrossOrigin(origins = "https://app.example.com") on a controller method. How does Spring MVC apply it?

  • A) It replaces Spring Security CSRF configuration entirely
  • B) It only affects @RequestBody JSON parsing
  • C) It configures CORS response headers for that handler via CorsInterceptor/CorsFilter processing in the MVC chain
  • D) It is ignored unless @EnableWebMvc is declared manually without Boot defaults
Answer & explanation

Correct answer: C

@CrossOrigin registers CORS configuration for the handler. DispatcherServlet/CORS processing adds appropriate Access-Control-* headers for preflight and actual requests matching the declared origins and methods.

Why the other options are wrong:

  • A) CORS and CSRF are related but distinct; @CrossOrigin does not replace CSRF config.
  • B) CORS affects browser cross-origin HTTP policy, not message converter selection.
  • D) Spring Boot MVC auto-config supports @CrossOrigin without manual @EnableWebMvc.

Memory sentence: "@CrossOrigin adds CORS headers for matching handlers in the MVC chain."

Study: Book chapter

Question 37

transfer is called outside an existing transaction. amount is negative after debit executes. What happens to the debit?

@Service
public class TransferService {
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepo.debit(from, amount);
if (amount.signum() < 0) throw new IllegalArgumentException("negative");
accountRepo.credit(to, amount);
}
}
  • A) Debit commits because IllegalArgumentException is unchecked and never rolls back
  • B) Debit persists because rollback requires @Transactional(rollbackFor = Exception.class) only
  • C) Default @Transactional rolls back on RuntimeException; debit is rolled back
  • D) JPA automatically compensates with a credit
Answer & explanation

Correct answer: C

Default @Transactional rolls back on RuntimeException and Error. IllegalArgumentException triggers rollback, undoing debit within the same transaction boundary. Checked exceptions do not roll back by default.

Why the other options are wrong:

  • A) Unchecked exceptions roll back by default, opposite of this claim.
  • B) rollbackFor extends rollback; default already covers RuntimeException.
  • D) No automatic compensation; transaction rollback handles consistency.

Memory sentence: "Default @Transactional rolls back on RuntimeException and Error."

Study: Book chapter

Question 38

A repository declares Optional<Customer> findByEmail(String email);. Spring Data JPA derives the query from the method name. What SQL shape is generated?

  • A) SELECT c FROM Customer c WHERE c.email = :email with limit 2 enforced
  • B) Native DELETE statement because Optional implies mutation
  • C) Query selecting Customer where email equals parameter; Optional return type does not change the WHERE clause
  • D) JOIN FETCH all collections automatically
Answer & explanation

Correct answer: C

Derived query methods translate findByEmail into a query filtering on the email property. Optional is a Java return-type wrapper handled by the persistence provider; it does not alter query semantics except expecting zero or one row.

Why the other options are wrong:

  • A) No automatic limit 2; uniqueness violations may throw NonUniqueResultException.
  • B) findBy prefix indicates read query, not delete.
  • D) JOIN FETCH requires explicit fetch join syntax in method name or @Query.

Memory sentence: "findByEmail → WHERE email = ?; Optional wraps zero/one result."

Study: Book chapter

Question 39

orderRepo.save(newOrder) is called where newOrder has transient LineItem children added with setOrder(this). What persists?

@Entity
public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.PERSIST)
private List<LineItem> items = new ArrayList<>();
}

@Entity
public class LineItem {
@ManyToOne
private Order order;
}
  • A) Only Order; LineItem requires explicit itemRepo.save each
  • B) Nothing until flush; cascade never works on @OneToMany
  • C) Order and LineItems because cascade PERSIST propagates to associated children linked through mappedBy side
  • D) LineItems only
Answer & explanation

Correct answer: C

CascadeType.PERSIST on @OneToMany propagates persist to associated LineItem entities when Order is persisted, provided bidirectional associations are set (lineItem.setOrder(order)). mappedBy indicates Order is inverse side but cascade still flows from owner operations initiated via persist of parent when configured.

Why the other options are wrong:

  • A) Cascade PERSIST removes need for separate saves of children.
  • B) Cascade works on @OneToMany when configured; flush timing does not negate cascade.
  • D) Parent save drives cascade to children, not children alone.

Memory sentence: "Cascade PERSIST on @OneToMany saves children when parent is persisted."

Study: Book chapter

Question 40

An entity graph causes N+1 queries loading Order with LineItems in a REST endpoint.

Which JPA approach directly targets fetch strategy for this read use case?

  • A) Change generation strategy to IDENTITY only
  • B) Mark Order @Transactional
  • C) @EntityGraph on repository query or JOIN FETCH in @Query to load associations in one round trip
  • D) Switch from JPA to JDBC Template without changing fetch plan
Answer & explanation

Correct answer: C

N+1 arises when lazy associations are accessed per row. @EntityGraph or JOIN FETCH eagerly fetches defined associations in the initial query, reducing round trips. Identity generation and @Transactional on entity do not fix fetch graphs.

Why the other options are wrong:

  • A) ID generation strategy unrelated to fetch N+1.
  • B) @Transactional on entity is invalid/meaningless for fetch tuning.
  • D) JDBC may help but the JPA-native fix is entity graph or fetch join.

Memory sentence: "N+1 fix: @EntityGraph or JOIN FETCH the needed associations."

Study: Book chapter

Question 41

What optimizations may readOnly = true enable on supported JPA providers?

@Transactional(readOnly = true)
public List<ReportRow> buildReport() {
return repo.heavyAggregationQuery();
}
  • A) Guaranteed distributed cache hit
  • B) Automatic switch to serializable transaction isolation
  • C) Hibernate may skip dirty checking and treat the persistence context as read-optimized for the transaction
  • D) Disables SQL execution entirely
Answer & explanation

Correct answer: C

readOnly=true hints that no state mutation occurs. Hibernate can optimize by avoiding flush/dirty checking overhead and, with some datasources, marking JDBC read-only. It does not disable SQL or guarantee caching.

Why the other options are wrong:

  • A) No guaranteed cache behavior from readOnly alone.
  • B) Isolation level is separate configuration.
  • D) Read queries still execute SQL.

Memory sentence: "readOnly=true hints no writes — provider may skip dirty checking."

Study: Book chapter

Question 42

Spring Data JPA @Modifying @Query("delete from Stock s where s.warehouse = ?1") int clearWarehouse(String w); must be used with what transactional consideration?

  • A) No transaction needed for delete queries
  • B) Only works inside @Transactional(readOnly = true)
  • C) Typically requires @Transactional on the calling service or repository method; may need clearAutomatically / flushAutomatically for consistency
  • D) @Modifying queries cannot be used with derived delete methods
Answer & explanation

Correct answer: C

@Modifying queries execute DML and require an active transaction. Developers often add @Transactional on the service layer and configure clearAutomatically to refresh persistence context after bulk operations.

Why the other options are wrong:

  • A) DML without transaction fails or behaves inconsistently across providers.
  • B) readOnly transactions forbid writes.
  • D) @Modifying applies to @Query DML; derived delete methods exist separately.

Memory sentence: "@Modifying DML needs a write transaction and often clearAutomatically."

Study: Book chapter

Question 43

Two transactions read the same Product version=3. Both modify price and save. What is expected?

@Entity
public class Product {
@Version
private Long version;
}
  • A) Last commit wins silently always
  • B) Database deadlocks are guaranteed
  • C) Second commit likely throws OptimisticLockException because @Version increments on first successful update
  • D) @Version blocks all concurrent reads
Answer & explanation

Correct answer: C

JPA optimistic locking uses @Version. First transaction succeeds incrementing version. Second update uses stale version in WHERE clause, affecting zero rows, leading to OptimisticLockException on flush/commit.

Why the other options are wrong:

  • A) Optimistic locking detects lost updates; not silent last-writer-wins.
  • B) Deadlock is not guaranteed; this is optimistic conflict detection.
  • D) Reads proceed; conflict appears on conflicting writes.

Memory sentence: "Stale @Version on update → OptimisticLockException, not silent overwrite."

Study: Book chapter

Question 44

A @Transactional service method calls another @Transactional method in the same class via this.internal().

Why might @Transactional on internal() be ignored?

  • A) Transactions never work on private methods only; public internal() always joins
  • B) Both methods always run in separate transactions regardless
  • C) Spring AOP proxies do not intercept self-invocation through this; only external calls through the proxy apply transaction advice
  • D) Spring Boot disables declarative transactions
Answer & explanation

Correct answer: C

Transaction management uses proxies. Calling this.internal() bypasses the proxy, so @Transactional on internal() may not start a new transaction or join as expected. External calls through injected self-proxy or refactoring fixes this.

Why the other options are wrong:

  • A) Public method self-invocation still bypasses proxy; visibility is not the sole factor.
  • B) Without proxy interception, internal() may run without transactional advice at all.
  • D) Boot enables @EnableTransactionManagement via auto-config.

Memory sentence: "this.internal() bypasses transactional proxy — self-invocation trap."

Study: Book chapter

Question 45

In Spring Security 6 lambda DSL, what does anyRequest().authenticated() mean for GET /admin?

http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(withDefaults());
  • A) Permitted anonymously because formLogin enables all GET requests
  • B) Requires ROLE_ADMIN implicitly
  • C) Requires an authenticated principal; unauthenticated users are redirected to login for browser requests
  • D) CSRF token exempts /admin from authentication
Answer & explanation

Correct answer: C

anyRequest().authenticated() mandates authentication for requests not matched by prior permitAll rules. formLogin configures a login flow; browser clients typically receive redirect to /login, while APIs may receive 401 depending on entry point configuration.

Why the other options are wrong:

  • A) formLogin does not bypass authentication for protected paths.
  • B) authenticated() is not role-specific; ROLE_ADMIN would need hasRole("ADMIN").
  • D) CSRF is separate from authentication requirements.

Memory sentence: "anyRequest().authenticated() = must be logged in; not role-specific."

Study: Book chapter

Question 46

A BCryptPasswordEncoder bean verifies login. Where should raw passwords be compared to stored hashes?

  • A) Direct string equals in the controller
  • B) Only inside JWT signature validation automatically
  • C) In the JPA entity setter for password
  • D) AuthenticationProvider or UserDetailsService flow delegating to PasswordEncoder.matches(raw, encoded)
Answer & explanation

Correct answer: D

Spring Security authentication uses PasswordEncoder.matches to compare presented credentials with stored encoded passwords. Controllers and entity setters must not perform manual password verification logic.

Why the other options are wrong:

  • A) Controllers should not handle credential comparison.
  • B) JWT validation verifies token integrity, not bcrypt login comparison directly.
  • C) Entities should not own authentication logic.

Memory sentence: "Login compare raw vs hash with PasswordEncoder.matches in auth flow."

Study: Book chapter

Question 47

Which capability does SpEL provide in this @PreAuthorize expression?

@PreAuthorize("hasRole('MANAGER') and #invoice.customerId == authentication.principal.customerId")
public InvoiceDto getInvoice(Invoice invoice) { }
  • A) Compile-time enforcement only without runtime checks
  • B) Automatic database row lock
  • C) Replacement of method security with URL-based authorizeHttpRequests only
  • D) Access to method arguments (#invoice) and Authentication principal for fine-grained authorization
Answer & explanation

Correct answer: D

Method security SpEL can reference method parameters with #name and authentication details. This enables data-centric authorization beyond static roles at the URL layer.

Why the other options are wrong:

  • A) @PreAuthorize is evaluated at runtime before method execution.
  • B) Authorization expression does not imply locking.
  • C) Method security complements URL security; it does not replace it.

Memory sentence: "@PreAuthorize SpEL can use #params and authentication.principal."

Study: Book chapter

Question 48

A stateless REST API uses JWT bearer tokens. SessionCreationPolicy is STATELESS.

What is true about HttpSession usage?

  • A) Spring Security still creates sessions for CSRF tokens always
  • B) STATELESS disables authentication entirely
  • C) JWT requires server HTTP session to store the token
  • D) No server session is created for authentication state; each request is authenticated via the bearer token filter chain
Answer & explanation

Correct answer: D

STATELESS policy prevents Spring Security from creating or using HttpSession for security context persistence. JWT-bearing requests authenticate per request through the filter chain without server-side session state.

Why the other options are wrong:

  • A) Stateless APIs typically disable CSRF for bearer usage; sessions are not created for auth.
  • B) STATELESS removes session storage, not authentication.
  • C) Bearer tokens travel in Authorization header; server need not store them in session.

Memory sentence: "STATELESS = no security HttpSession; JWT auth per request."

Study: Book chapter

Question 49

CORS preflight OPTIONS request hits /api/data. Spring Security is configured with cors(withDefaults()). Who responds to OPTIONS?

  • A) Browser only; server never sees OPTIONS
  • B) OPTIONS always requires ADMIN role
  • C) DispatcherServlet rejects OPTIONS unless @CrossOrigin absent
  • D) CORS filter/integration may authorize OPTIONS before authentication while adding CORS headers per configuration
Answer & explanation

Correct answer: D

CORS integration handles preflight OPTIONS requests, often permitting them without authentication while returning allowed origins/methods/headers. Actual data requests still require normal auth rules.

Why the other options are wrong:

  • A) Preflight OPTIONS is sent to the server.
  • B) Preflight is not typically ADMIN-gated.
  • C) @CrossOrigin and global CORS config enable handling; OPTIONS is not blindly rejected.

Memory sentence: "CORS preflight OPTIONS often permitted separately from authenticated GET/POST."

Study: Book chapter

Question 50

@WithMockUser(roles = "ADMIN") is used on a @WebMvcTest slice for AdminController.

What does this annotation provide?

  • A) A full integration test against a real database user table
  • B) Automatic JWT token minting against OAuth server
  • C) Disables Spring Security for the test
  • D) A SecurityContext with a mock authenticated user for the test request, without hitting UserDetailsService
Answer & explanation

Correct answer: D

@WithMockUser populates the SecurityContext with a synthetic principal and granted authorities for slice/full MVC tests, enabling authorization checks without loading real users.

Why the other options are wrong:

  • A) It is a test shortcut, not database-backed authentication.
  • B) No OAuth/JWT issuance occurs.
  • C) Security remains active with a mocked user.

Memory sentence: "@WithMockUser fakes SecurityContext principal for MVC tests."

Study: Book chapter

Question 51

Which beans are loaded in the test ApplicationContext?

@WebMvcTest(controllers = InvoiceController.class)
class InvoiceControllerTest {
@Autowired MockMvc mockMvc;
@MockBean InvoiceService invoiceService;
}
  • A) Full application including JPA repositories and DataSource
  • B) Only InvoiceController with no MockMvc
  • C) Entire Spring Security filter chain from main always without configuration
  • D) Web layer slice: MVC infrastructure, InvoiceController, and mocked InvoiceService replacement
Answer & explanation

Correct answer: D

@WebMvcTest loads a limited MVC-focused context for the specified controller, auto-configuring MockMvc and Spring Security when on classpath. @MockBean replaces InvoiceService in the context for isolation.

Why the other options are wrong:

  • A) Full @SpringBootTest loads everything; @WebMvcTest is a slice.
  • B) MockMvc is auto-configured in @WebMvcTest.
  • C) Security test support is partial unless imported; not guaranteed full main chain.

Memory sentence: "@WebMvcTest = controller slice + MockMvc + @MockBean collaborators."

Study: Book chapter

Question 52

@DataJpaTest loads an in-memory database by default. Which statement is correct?

  • A) It starts the full web environment on a random port
  • B) It replaces @Entity classes with mocks
  • C) It requires @SpringBootTest on the same class
  • D) It configures JPA test infrastructure, repositories under test, and rolls back transactions after each test method by default
Answer & explanation

Correct answer: D

@DataJpaTest is a JPA slice importing auto-configuration for TestEntityManager, in-memory DataSource (typically), and @Transactional rollback per test method unless @Commit is used.

Why the other options are wrong:

  • A) Web environment is not started in @DataJpaTest.
  • B) Real @Entity mapping is tested, not mocked entities.
  • C) @DataJpaTest is self-contained; @SpringBootTest is not required.

Memory sentence: "@DataJpaTest = JPA slice, in-memory DB, transactional rollback per test."

Study: Book chapter

Question 53

This is a focused unit/integration hybrid without @SpringBootTest. What is true?

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {OrderService.class, TestConfig.class})
class OrderServiceTest {
@Autowired OrderService orderService;
@MockBean PaymentGateway gateway;
}
  • A) @MockBean requires @SpringBootTest always
  • B) @ContextConfiguration cannot load @Service classes
  • C) PaymentGateway mock is injected only if @InjectMocks is present
  • D) SpringExtension builds a context from specified classes; @MockBean adds Mockito mocks as beans
Answer & explanation

Correct answer: D

Spring TestContext Framework can load minimal configurations via @ContextConfiguration. @MockBean (or @MockitoBean in newer versions) registers mocks in the context, letting @Autowired services receive them.

Why the other options are wrong:

  • A) @MockBean works in sliced/custom contexts with SpringExtension.
  • B) @Service classes are valid context configuration entries.
  • C) @InjectMocks is pure Mockito; here Spring injects the @MockBean into OrderService.

Memory sentence: "@ContextConfiguration + @MockBean builds minimal Spring test contexts."

Study: Book chapter

Question 54

@SpringBootTest(webEnvironment = RANDOM_PORT) with TestRestTemplate calls actuator /health.

What does RANDOM_PORT imply?

  • A) No servlet container starts; TestRestTemplate is inert
  • B) Only MockMvc can be used
  • C) Port 8080 is hard-coded
  • D) Embedded server starts on a random available port; tests use real HTTP against localhost
Answer & explanation

Correct answer: D

RANDOM_PORT starts the full embedded web server on an ephemeral port. TestRestTemplate or WebTestClient can issue real HTTP requests, suitable for integration tests including actuator endpoints.

Why the other options are wrong:

  • A) Servlet container does start in web environments.
  • B) MockMvc is for in-process MVC; RANDOM_PORT enables real HTTP clients.
  • C) Port is random, not fixed 8080.

Memory sentence: "RANDOM_PORT = real embedded server on ephemeral port for HTTP tests."

Study: Book chapter

Question 55

@TestConfiguration inside a test class defines extra beans. How does it differ from main @Configuration?

  • A) It replaces application.properties permanently
  • B) It runs before main sources always in production
  • C) It cannot define @Bean methods
  • D) It is not picked up by component scanning in production and is imported explicitly for tests
Answer & explanation

Correct answer: D

@TestConfiguration is a specialized @Configuration not auto-scanned in production. Tests import it via @Import, @SpringBootTest classes attribute, or nested static class patterns to override or add beans.

Why the other options are wrong:

  • A) It does not mutate production property files.
  • B) It is test-scoped, not production startup.
  • C) @Bean methods are commonly defined in test configuration.

Memory sentence: "@TestConfiguration = test-only beans, not production-scanned."

Study: Book chapter

Question 56

Which libraries are idiomatic for these assertions in Spring service tests?

verify(gateway, times(1)).charge(any());
assertThat(result.getStatus()).isEqualTo(OrderStatus.PAID);
  • A) JUnit 4 Hamcrest only
  • B) Spring MVC Test only
  • C) JdbcTemplate queryForObject
  • D) Mockito verify for interactions and AssertJ assertThat for fluent assertions
Answer & explanation

Correct answer: D

Modern Spring tests combine Mockito (verify, when) for collaborator behavior with AssertJ fluent assertions for readable state checks. JUnit 5 is the baseline test engine in Boot 3.

Why the other options are wrong:

  • A) JUnit 5 with AssertJ is the modern default, not JUnit 4 only.
  • B) MVC Test targets controllers, not service Mockito verify patterns.
  • C) JdbcTemplate is unrelated to these assertion APIs.

Memory sentence: "Service tests: Mockito verify + AssertJ assertThat on JUnit 5."

Study: Book chapter

Question 57

@Transactional is applied to charge(). External client calls chargeWrapper() through the Spring proxy. What happens?

@Service
public class BillingService {
@Transactional
public void charge() { ledger.post(); }

public void chargeWrapper() { charge(); }
}
  • A) Transaction starts because charge() is @Transactional regardless of entry method
  • B) chargeWrapper automatically inherits @Transactional from callee
  • C) CGLIB merges both methods into one transactional boundary always
  • D) Transaction advice may not apply: internal call from chargeWrapper() to charge() bypasses proxy
Answer & explanation

Correct answer: D

Same self-invocation limitation as transactional AOP: chargeWrapper() calling this.charge() internally does not pass through the proxy, so @Transactional on charge() may not activate when entered via chargeWrapper().

Why the other options are wrong:

  • A) Proxy applies to external calls through the proxy bean, not internal this calls.
  • B) Annotations are not inherited across methods automatically.
  • C) CGLIB does not retroactively wrap internal method calls.

Memory sentence: "Internal this.charge() from non-advised method skips @Transactional proxy."

Study: Book chapter

Question 58

What is required for this listener to run asynchronously on a separate thread?

@EventListener
@Async
public void handle(OrderPlacedEvent event) { email.send(event); }
  • A) Only @EventListener is enough; async is default
  • B) @Transactional on the listener method
  • C) Replacing ApplicationEventPublisher with JMS only
  • D) @EnableAsync and an Executor bean or Spring Boot auto-configured task executor
Answer & explanation

Correct answer: D

@Async methods run through Spring task execution infrastructure, enabled by @EnableAsync (Boot auto-configures when present). Without async execution enabled, @Async may run synchronously or fail depending on configuration.

Why the other options are wrong:

  • A) Event listeners are synchronous unless @Async infrastructure is enabled.
  • B) @Transactional does not provide async thread dispatch.
  • C) In-process async events do not require JMS.

Memory sentence: "@Async listeners need @EnableAsync and a TaskExecutor."

Study: Book chapter

Question 59

ApplicationEventPublisher publishes a custom OrderCancelledEvent after transaction commit is desired. Which annotation ensures listeners see committed data?

  • A) @EventListener alone always waits for commit
  • B) @Async only
  • C) @Order(0)
  • D) @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
Answer & explanation

Correct answer: D

@TransactionalEventListener with AFTER_COMMIT schedules event handling only if the transaction commits successfully, preventing listeners from reading uncommitted state.

Why the other options are wrong:

  • A) Plain @EventListener fires immediately, not necessarily after commit.
  • B) @Async affects thread, not transaction phase alignment.
  • C) @Order controls listener ordering, not transaction commit phase.

Memory sentence: "AFTER_COMMIT transactional listener runs only if TX succeeds."

Study: Book chapter

Question 60

Micrometer Timer metric order.latency is registered. management.tracing.enabled=true with OpenTelemetry bridge.

Which outcome is most accurate in a Boot 3 observability setup?

  • A) Metrics and traces are mutually exclusive; enabling tracing disables timers
  • B) Actuator /health automatically includes full distributed trace trees
  • C) Observability requires replacing Logback with Log4j1
  • D) Order handler can record Timer metrics while HTTP requests also propagate trace spans through Micrometer Observation or OTel bridge
Answer & explanation

Correct answer: D

Spring Boot 3 integrates Micrometer Observation linking metrics, logging, and tracing. Custom Timer metrics coexist with distributed tracing when tracing dependencies and properties are configured.

Why the other options are wrong:

  • A) Metrics and tracing complement each other via Observation API.
  • B) Health endpoint reports health status, not full trace trees.
  • C) Log implementation choice is independent of metrics/tracing bridge.

Memory sentence: "Boot 3 Observation links metrics, logs, and traces — they coexist."

Study: Book chapter


End of Mock Full 06 — Spring Professional (60 Questions)