Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
Chaturmind
← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 8+ Years (Senior & Lead)Spring & Spring Boot Internals
✓ FreeAdvanced· 15 min read

Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions

@ComponentScan vs @Import, precedence between XML, Java config and @Value, mixing XML and Java config, @Configuration vs @Component (full vs lite mode), @Bean lifecycle, duplicate @Bean types, overriding library beans, environment-aware configuration, multiple scan packages, @Bean outside @Configuration, how auto-configuration works (AutoConfiguration.imports, conditions, ordering), enabling/disabling it, conditional beans, starters that never clash with Boot, a cloud messaging starter design, @TestConfiguration vs @SpringBootTest, test profiles, multiple active profiles, YAML and encrypted properties, Docker configuration per environment, a production misconfiguration story, and multi-module Spring Boot architecture.

Published September 25, 2026


How to use this lesson

Configuration questions check whether you can predict which bean and which property value win, and whether you can build platform starters that behave well. Anchor your answers in conditions, ordering and property-source precedence.

Q1. What's the difference between @ComponentScan and @Import?

Short answer:

  • @ComponentScan discovers classes annotated with @Component (and its stereotypes) by scanning packages on the classpath. It's implicit and broad.
  • @Import explicitly registers specific classes: @Configuration classes, **ImportSelector**s (which choose the classes to import programmatically) or **ImportBeanDefinitionRegistrar**s (which register definitions directly). No scanning happens.

Boot's @SpringBootApplication scans the application's package. Auto-configuration and @Enable* annotations use imports (for example, @EnableScheduling imports a configuration). Use @Import for libraries and modules, so consumers don't depend on package scanning.

Learn it in depth → Component Scanning & Configuration

Q2. What's the precedence between XML, Java config and @Value?

Short answer: They configure different things, so separate bean definitions from property values:

  • Bean definitions: if the same bean name is defined twice, the last definition registered wins, but only if overriding is allowed. Spring Boot disables bean-definition overriding by default (spring.main.allow-bean-definition-overriding=false), so startup fails. In plain Spring, the registration order depends on how the configurations are imported (for example, @ImportResource XML processed after the class's own @Beans).
  • @Value("${prop}") doesn't have "precedence" over XML or Java config. It reads from the Environment, whose property sources have a defined order (command-line arguments > system properties > environment variables > external and internal config files > defaults).
  • Explicit wiring vs annotations: explicit XML <property> values are applied after annotation injection, so they override field values set by @Autowired or @Value on the same bean.

Avoid designs that depend on overriding. Use conditions, profiles or @Primary.

Q3. How would you mix XML and Java-based configuration?

Short answer:

  • From Java into XML: @ImportResource("classpath:legacy-context.xml") on a @Configuration class.
  • From XML into Java: <context:annotation-config/> plus <bean class="com.acme.AppConfig"/>, or <context:component-scan> in the XML.
  • Beans from both sources live in one context, and can inject each other.

It's typical during migration of legacy applications. Move bean definitions to Java config incrementally, and keep the XML only for rarely changed or third-party definitions. Spring Boot still supports @ImportResource.

Q4. How does @Configuration differ from a regular @Component class that declares @Bean methods?

Short answer:

  • @Configuration (full mode): the class is CGLIB-proxied. Calls from one @Bean method to another are intercepted, and return the container singleton:
@Configuration
class DbConfig {
    @Bean DataSource dataSource() { return new HikariDataSource(); }
    @Bean JdbcTemplate jdbc() { return new JdbcTemplate(dataSource()); }   // same singleton DataSource, through the proxy
}
  • @Component or @Configuration(proxyBeanMethods = false) (lite mode): no proxy, so dataSource() is a plain Java call that creates a new HikariDataSource: a second pool, and a resource leak. Lite mode starts faster, and works with GraalVM native images. Boot's own auto-configurations use it, and inject dependencies as method parameters instead.

Q5. What is the @Bean lifecycle, and how does method-level configuration differ from field injection?

Short answer:

  • Lifecycle: the container calls the @Bean factory method (resolving its parameters as dependencies), then applies the normal lifecycle: population → aware callbacks → BeanPostProcessor before-init → @PostConstruct/afterPropertiesSet/initMethod → after-init (proxies) → ... → on shutdown, @PreDestroy/destroyMethod. destroyMethod is inferred by default (a public close() or shutdown() method is called automatically).

  • Compared with field injection:

    • @Bean methods receive dependencies as parameters, so the construction is explicit and testable;
    • they're ideal for third-party classes;
    • they can choose implementations conditionally;
    • they keep domain classes free of Spring annotations.

    Field injection hides dependencies, and only works on classes Spring instantiates itself.

Q6. What happens if two @Bean methods return the same type, without any qualifier?

Short answer: Both beans are registered, under their method names. Injecting by type then fails with NoUniqueBeanDefinitionException, unless:

  • one is marked @Primary;
  • the injection point uses @Qualifier("name"), or a parameter or field name that matches a bean name;
  • you inject a List<T>/Map<String,T> of all of them.

If the two methods have the same name (for example, in different configuration classes), Boot fails at startup, because overriding is disabled.

Q7. How do you override a Spring bean defined in a library dependency?

Short answer: It depends on how the library defines it:

  1. Auto-configured beans with @ConditionalOnMissingBean (most Boot starters): define your own bean of that type, and the auto-configuration backs off. This is the intended mechanism.
  2. Customiser hooks: many libraries expose *Customizer beans (Jackson2ObjectMapperBuilderCustomizer, RestClientCustomizer, WebServerFactoryCustomizer), so you can tweak the default instead of replacing it.
  3. Exclude the auto-configuration: spring.autoconfigure.exclude=..., or @SpringBootApplication(exclude = ...), then define your own.
  4. Same bean name, with spring.main.allow-bean-definition-overriding=true. It's a blunt instrument, and order-dependent, so avoid it.
  5. @Primary on your bean, if both can coexist.
  6. BeanDefinitionRegistryPostProcessor, to remove or replace definitions (a last resort).

Q8. What are the ways to make Spring configuration environment-aware?

Short answer:

  • Profiles: application-{profile}.yml, @Profile on beans, and spring.profiles.active, or profile groups (spring.profiles.group.prod=cloud,metrics).
  • Externalised properties: environment variables, system properties, command-line arguments, spring.config.import (configuration trees for Kubernetes secrets, Config Server, Vault, AWS Parameter Store).
  • Conditional beans: @ConditionalOnProperty, @ConditionalOnCloudPlatform, @ConditionalOnClass, custom @Conditionals.
  • Typed configuration: @ConfigurationProperties records, with @Validated, so every environment fails fast on bad values.
  • The platform: Kubernetes ConfigMaps and Secrets, with Spring Cloud Kubernetes, or mounted files.
  • Feature flags, for runtime behaviour changes.

Q9. What happens when @ComponentScan lists several packages?

Short answer: Spring scans all of them (@ComponentScan(basePackages = {"com.a", "com.b"}), or the type-safe basePackageClasses), and registers every candidate it finds. Overlapping packages are fine: each class is registered once, since definitions are keyed by bean name. But watch for:

  • duplicate bean names from different packages (two DefaultClient classes), which is a conflict;
  • scanning too broadly (for example, a whole library's packages), which picks up unwanted beans and slows startup;
  • the @SpringBootApplication default: declaring your own @ComponentScan replaces the default scanning of the main class's package and its auto-configuration exclusion filters, which is a common source of odd behaviour.

Put the main class in the root package, so the default scan covers everything, and use filters (includeFilters/excludeFilters) when needed.

Q10. Can you use @Bean in a class that isn't a @Configuration? What are the consequences?

Short answer: Yes. It's "lite mode". @Bean methods in a @Component, or even in a plain class registered as a bean, are processed. The consequence is that inter-bean method calls aren't intercepted, so calling another @Bean method directly creates a new instance, bypassing the container: duplicate singletons, lost lifecycle callbacks and no AOP. Fix: inject the dependencies through method parameters, and never call @Bean methods directly in lite mode.

Q11. What is auto-configuration, and how does it work under the hood? How does Boot decide which configuration classes to use?

Short answer:

  1. @SpringBootApplication includes @EnableAutoConfiguration, which imports AutoConfigurationImportSelector.
  2. The selector reads candidate classes from META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, in every JAR (Boot 2.7+). Previously, it read spring.factories.
  3. It removes exclusions (the exclude attributes, and spring.autoconfigure.exclude), and filters early using the condition metadata (fast checks of @ConditionalOnClass without loading classes).
  4. The remaining @AutoConfiguration classes are ordered (@AutoConfiguration(before/after), @AutoConfigureOrder), and processed after the user's configuration. So user beans are registered first, and @ConditionalOnMissingBean backs off correctly.
  5. Conditions decide which beans apply: @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty, @ConditionalOnWebApplication, @ConditionalOnBean, @ConditionalOnResource, @ConditionalOnCloudPlatform.
  6. Diagnose with --debug (the condition evaluation report) or /actuator/conditions.

Learn it in depth → Auto-Configuration Mechanism

Q12. What's the purpose of spring.factories, and of the AutoConfiguration.imports file?

Short answer: They're how auto-configurations are registered, so Boot can find them in JARs without scanning:

  • META-INF/spring.factories: the legacy key-value file. For auto-configuration (the EnableAutoConfiguration key), it was deprecated in Boot 2.7, and no longer supported for that purpose in Boot 3. It's still used for other extension points (for example ApplicationContextInitializer, EnvironmentPostProcessor, FailureAnalyzer).
  • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: the current file, with one fully qualified class name per line, for @AutoConfiguration classes.

Common trap: a custom starter that still registers its auto-configuration in spring.factories silently does nothing on Boot 3.

Q13. How do you enable or disable auto-configuration?

Short answer:

  • Enable it: @SpringBootApplication (or @EnableAutoConfiguration).
  • Disable specific classes:
    • @SpringBootApplication(exclude = DataSourceAutoConfiguration.class), or excludeName for classes not on the classpath;
    • spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration (a property, so it can be changed per environment).
  • Disable it entirely: don't use @EnableAutoConfiguration (use @Configuration + @ComponentScan), or set spring.boot.enableautoconfiguration=false.
  • Make it back off selectively: define your own bean, and the @ConditionalOnMissingBean defaults step aside.

Common trap: the source says spring.autoconfigure.exclude "disables all" auto-configuration. It excludes only the listed classes.

Q14. What is conditional bean loading?

Short answer: Registering beans only when conditions hold, evaluated at configuration time:

  • Core Spring: @Conditional(MyCondition.class) (implement Condition.matches), and @Profile (which is itself a condition).
  • Boot:
    • @ConditionalOnClass/OnMissingClass;
    • @ConditionalOnBean/OnMissingBean;
    • @ConditionalOnProperty;
    • @ConditionalOnResource;
    • @ConditionalOnWebApplication;
    • @ConditionalOnExpression;
    • @ConditionalOnJava;
    • @ConditionalOnCloudPlatform;
    • @ConditionalOnSingleCandidate;
    • @ConditionalOnThreading(VIRTUAL).

The caveats:

  • @ConditionalOnBean/OnMissingBean depend on registration order. They're reliable in auto-configurations (processed after user config), and unreliable in regular @Configuration classes.
  • Test your conditions with ApplicationContextRunner.

Q15. How do you make sure a custom starter doesn't interfere with Spring Boot's own auto-configuration?

Short answer:

  • Guard every bean with @ConditionalOnMissingBean, so users (and Boot) can provide their own.
  • Guard the whole configuration with @ConditionalOnClass: activate only when your library is present.
  • Offer @ConditionalOnProperty to switch it off (acme.feature.enabled=false).
  • Declare ordering relative to Boot's configurations: @AutoConfiguration(after = DataSourceAutoConfiguration.class).
  • Use your own property namespace (acme.*), never spring.*.
  • Expose customisers, instead of replacing Boot-managed beans (ObjectMapper, RestClient.Builder).
  • Never component-scan in a starter.
  • Register only through AutoConfiguration.imports.
  • Test the combinations with ApplicationContextRunner (with and without the user's beans, with the properties on and off).

Q16. You're building a custom starter for cloud message queuing, used by many microservices. What would it contain?

Short answer:

  • Modules: acme-messaging-spring-boot-autoconfigure (the logic), and acme-messaging-spring-boot-starter (dependencies only), plus a BOM for versions.
  • @ConfigurationProperties("acme.messaging"): provider (SQS, Pub/Sub, Service Bus), endpoints, credentials references (never raw secrets), retry and backoff, DLQ names, concurrency, and serialisation format. Validated, with IDE metadata.
  • Auto-configured beans:
    • a provider-neutral abstraction (MessagePublisher, and @AcmeListener or MessageHandler registration);
    • provider adapters, chosen through @ConditionalOnClass or properties;
    • a JSON or Avro serialiser with schema versioning;
    • retry and DLQ handling;
    • idempotent-consumer support (deduplication store hooks);
    • transactional outbox integration for publishing.
  • Platform integration:
    • Micrometer metrics (published, consumed, failures, lag) and tracing propagation (a trace context in message headers);
    • health indicators;
    • graceful shutdown through SmartLifecycle.
  • Security: workload identity or IAM roles, and TLS.
  • Quality: customisers, @ConditionalOnMissingBean everywhere, ApplicationContextRunner tests, Testcontainers or LocalStack integration tests, documentation, and a sample application.

Q17. How do @TestConfiguration and @SpringBootTest differ?

Short answer:

  • @SpringBootTest bootstraps the full application context (optionally with a real web server, webEnvironment = RANDOM_PORT), finding the @SpringBootConfiguration. It's for integration tests.

  • @TestConfiguration adds or overrides beans for tests only:

    • as a nested static class inside a test, it's picked up automatically;
    • as a top-level class, you include it with @Import.

    It's excluded from component scanning, so it doesn't leak into other tests. For example, a fixed Clock, a fake payment gateway, or a Testcontainers-backed DataSource.

Use them together: @SpringBootTest plus @Import(TestClockConfig.class). Remember that every distinct configuration creates a new cached context, which slows the test suite.

Q18. How do you load test-specific beans using profiles?

Short answer:

  • Annotate test-only beans or configurations with @Profile("test").
  • Activate the profile in tests with @ActiveProfiles("test"), and use application-test.yml for test properties.
  • Prefer @TestConfiguration plus @Import for bean overrides, and @TestPropertySource or @DynamicPropertySource (with Testcontainers) for properties. Those are more explicit than profiles, and don't risk leaking test beans into production if someone activates the "test" profile.
  • Never put test doubles in src/main guarded only by a profile.

Q19. If several application-<profile>.yml files are active, which one wins?

Short answer: The last profile listed wins for conflicting keys. With spring.profiles.active=dev,local, the values in application-local.yml override application-dev.yml, and all profile-specific files override application.yml. Profile-specific files outside the JAR override those inside it. Environment variables and command-line arguments override all of them. Within a multi-document YAML, later documents override earlier ones for matching activation conditions. Use profile groups to define a stable order.

Q20. How do you use YAML configuration, and how do you encrypt properties?

Short answer:

  • YAML:
    • application.yml, with hierarchical keys and lists;
    • multi-document files separated by ---, with spring.config.activate.on-profile;
    • bind them to @ConfigurationProperties records, rather than scattered @Values;
    • quote strings that look like booleans or octal numbers;
    • remember that .properties wins over .yml in the same location.
  • Encryption and secrets:
    • Best practice: don't store secrets in files at all. Use Vault (spring.config.import=vault://), AWS Secrets Manager or Parameter Store, Azure Key Vault, Kubernetes Secrets (mounted as a configuration tree), or sealed secrets or SOPS in GitOps.
    • Encrypted values in configuration: Spring Cloud Config Server supports {cipher}... values, decrypted server-side or client-side with a symmetric key or a key store. Jasypt (ENC(...)) is a common library alternative. The key itself must come from outside the repository (an environment variable or a KMS).
    • Mask secrets in /actuator/env and logs.

Q21. How do you manage configuration for a Dockerised Spring Boot application across environments?

Short answer: One immutable image, configuration injected at runtime:

  • Environment variables, using relaxed binding (SPRING_DATASOURCE_URL, APP_PAYMENTS_TIMEOUT), set through Compose, Kubernetes manifests, or Helm values per environment.
  • Mounted configuration files or configuration trees (spring.config.import=optional:configtree:/etc/config/) from Kubernetes ConfigMaps and Secrets.
  • SPRING_PROFILES_ACTIVE, for environment-specific defaults that ship inside the JAR (non-secret).
  • Central configuration and secret stores (Config Server, Vault, a cloud parameter store), for dynamic or shared settings.
  • Never bake environment-specific values or secrets into the image.
  • Validate the configuration at startup (@Validated properties), and version configuration changes in Git (GitOps), with review.

Q22. Tell me about a time a properties misconfiguration caused a production issue.

Short answer: Answer with a STAR story. A realistic example: a new release set spring.datasource.hikari.maximum-pool-size=100 per pod, while the autoscaler went to 20 pods. That's 2,000 connections against a database limited to 500. Under peak traffic, connections failed, requests timed out, and the database CPU spiked.

  • Detection: alerts on 5xx rates and Hikari's pending-connection metrics, plus database connection-limit errors in the logs.
  • Mitigation: rolled back the configuration through GitOps (with no image rebuild needed), and scaled the pods down temporarily.
  • The permanent fixes:
    • pool sizing derived from database capacity ÷ maximum replicas;
    • validation of configuration ranges in @ConfigurationProperties;
    • configuration changes going through the same review, CI checks and canary rollout as code;
    • dashboards on pool saturation;
    • a runbook.

The lesson: configuration is code. Other classic examples: timeouts set too low, a wrong profile active in production (dev configuration, or H2 used), and feature flags defaulting to on.

Q23. What is a multi-module Spring Boot architecture?

Short answer: It splits one application (or a platform) into Maven or Gradle modules, with explicit dependencies:

  • Domain (pure Java, no Spring);
  • application or use cases;
  • adapters: web, persistence, messaging;
  • a bootable app module that assembles them with the Spring Boot plugin;
  • shared *-api modules, for contracts.

The benefits:

  • enforced boundaries (the domain can't import JPA);
  • faster, incremental builds;
  • reusable modules (a starter, or a client library);
  • a clear place for each concern (a hexagonal or modular monolith).

The practices:

  • a parent POM or version catalogue with Boot's BOM;
  • only the app module uses the Boot plugin (the library modules produce plain JARs);
  • test slices per module;
  • ArchUnit or Spring Modulith to verify module dependencies, and events between modules.

Follow-up questions this topic invites — and their answers

Q: What is @ConfigurationProperties scanning? A: @ConfigurationPropertiesScan (or @EnableConfigurationProperties(MyProps.class)) registers property classes as beans. Records get constructor binding automatically (Boot 3). Add the spring-boot-configuration-processor for IDE metadata.

Q: How do you see why a bean was, or wasn't, auto-configured? A: Run with --debug, or logging.level.org.springframework.boot.autoconfigure=DEBUG, or check /actuator/conditions. The report lists positive and negative matches, with the exact condition outcomes.

Q: What is an EnvironmentPostProcessor? A: A hook (registered in spring.factories) that customises the Environment before the context refreshes. It adds property sources, or decrypts or derives values. It's used by configuration libraries and cloud integrations.

Q: Can @Value inject lists and defaults? A: Yes: @Value("${app.hosts:localhost}") for a default, and SpEL #{'${app.hosts}'.split(',')} for lists. @ConfigurationProperties is cleaner for structured configuration, and supports relaxed binding and validation.

Previous

Spring AOP, Proxies & @Async Internals — Interview Questions

Next

Spring MVC & REST Internals, Exception Frameworks — Interview Questions

AI Tutor

Lesson: Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.