skip to content

Container Services

The supporting services the container offers beyond wiring: resource loading, type conversion and formatting, application events, message sources for i18n, and Bean Validation integration. Interviewers dip in here when they want breadth rather than Boot trivia.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

page 1 of 2

How do you publish and receive an application event in Spring?

level: juniorimportance: must knowfreq 70%

answer

  1. publishEvent on ApplicationEventPublisher
  2. @EventListener single-param method
  3. any POJO since 4.2
  4. synchronous, publisher thread, by default
  5. listener exception bubbles to publisher

basics

~10 s

Inject ApplicationEventPublisher and call publishEvent(event). Receive it with a method annotated @EventListener whose single parameter matches the event type. Spring calls that method when a matching event is published.

solid answer

~40 s

Spring has a built-in in-process publish/subscribe mechanism. To publish, inject ApplicationEventPublisher (any bean can, since it is aware of the context) and call publishEvent(someObject). To listen, annotate a bean method with @EventListener and declare one parameter of the event type; Spring routes matching events to it. Since Spring 4.2 the event can be any POJO — you no longer need to extend the old ApplicationEvent base class. Listeners run synchronously in the publisher's thread by default, so publishEvent returns only after all listeners finish. This decouples the producer from consumers: the publisher does not know who listens. In KataJob, UserRegistered is published this way, even though no consumer exists yet.

code

java · 24 lines
java
// Publisher
@Service
class RegistrationService {
    private final ApplicationEventPublisher publisher;
    RegistrationService(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }
    void register(String email) {
        // ...persist the user...
        publisher.publishEvent(new UserRegistered(email)); // plain POJO event
    }
}

record UserRegistered(String email) {}

// Listener
@Component
class WelcomeMailer {
    @EventListener
    void on(UserRegistered event) {
        // runs synchronously on the caller's thread
        System.out.println("Welcome " + event.email());
    }
}

go deeper

for a junior

Know the two moving parts: publishEvent to send, @EventListener to receive.

for a middle

Add that it's synchronous by default and events can be plain POJOs.

for a senior

Discuss exception propagation aborting the publisher and decoupling within a modular monolith.

for a principal

Frame events as an in-process, unpersisted decoupling tool and know its failure/ordering semantics.

## What application events are Spring's ApplicationContext is also an event bus. It lets one bean announce that something happened without knowing who (if anyone) reacts. This is the Observer / publish-subscribe pattern, built into the container. ## Publishing Inject `org.springframework.context.ApplicationEventPublisher` into any bean and call `publishEvent(Object event)`: ```java @Service class RegistrationService { private final ApplicationEventPublisher publisher; RegistrationService(ApplicationEventPublisher publisher) { this.publisher = publisher; } void register(User u) { // ... persist ... publisher.publishEvent(new UserRegistered(u.getId())); } } ``` The `ApplicationContext` itself implements `ApplicationEventPublisher`, so you can also autowire the context, but injecting the narrower `ApplicationEventPublisher` interface is cleaner. ## The event object - **Legacy style:** extend `org.springframework.context.ApplicationEvent` (requires a source constructor arg). - **Modern style (Spring 4.2+):** the event can be **any object** — a plain POJO/record. Spring internally wraps non-ApplicationEvent payloads in a `PayloadApplicationEvent<T>`, but you rarely see that. ## Listening Annotate a bean method with `@org.springframework.context.event.EventListener` and give it exactly one parameter of the event type: ```java @Component class WelcomeMailer { @EventListener void on(UserRegistered e) { /* send email */ } } ``` The method may have any name, any visibility (Spring uses reflection), and may return `void` or another event object (returning an event re-publishes it). You can also match by supertype/interface: a listener for `Object` receives every event. The older alternative is implementing the `ApplicationListener<E extends ApplicationEvent>` interface with an `onApplicationEvent` method — still valid, but `@EventListener` is the idiomatic modern choice because it needs no interface and supports SpEL conditions. ## Execution model - **Synchronous by default.** `publishEvent` does not return until every matching listener has run, on the **publisher's thread**. - **Ordered** among listeners via `@Order` / `Ordered`, otherwise unspecified. - **Exceptions propagate.** A listener throwing an exception (in sync mode) aborts the remaining listeners and bubbles up to the caller of `publishEvent`. So a failed listener can break the publisher's flow — a common surprise. ## When to use Use events to decouple modules inside one process: the producer emits a fact, consumers react. In a Spring Modulith app like KataJob, events are the sanctioned way for one module to notify others without a compile-time dependency. Do not use them as a substitute for a direct method call when you actually need a synchronous return value or strong coupling. ## Gotchas - Nothing is persisted or retried — this is an in-memory bus; if the JVM dies, in-flight events are lost. - Having zero listeners is legal and silent (like KataJob's UserRegistered). - Because it is synchronous, a slow listener slows the publisher.

  • Do you have to extend ApplicationEvent for your event class?
    No. Since Spring 4.2 any object works as an event; Spring wraps it in a PayloadApplicationEvent internally. Extending ApplicationEvent is the older style and optional.
  • On which thread does a listener run by default?
    The publisher's thread — event delivery is synchronous, so publishEvent blocks until all listeners complete unless you make them @Async.

saying these in an interview costs you the question

  • Thinking every event class must extend ApplicationEvent
  • Assuming listeners run asynchronously by default
  • Believing a listener exception is swallowed and never affects the publisher

context

open as a page

What is Bean Validation (JSR-380) and how does Spring expose a Jakarta Validator you can inject?

level: juniorimportance: must knowfreq 60%

basics

~10 s

Bean Validation is a standard for declaring rules on fields with annotations like @NotNull and @Size. Spring's LocalValidatorFactoryBean builds a Validator you can inject and call validate() on.

open as a page

What is Spring's ConversionService, and how does it relate to converting a String from @Value into a typed field like an int or Duration?

level: juniorimportance: must knowfreq 55%

basics

~10 s

ConversionService is Spring's central component for converting one type to another (e.g. String to int). When @Value injects a text value, Spring uses it to coerce the String into the field's declared type.

open as a page

What is Spring's DataBinder and what problem does it solve?

level: juniorimportance: must knowfreq 55%

basics

~10 s

DataBinder takes a bag of name/value pairs (like form fields) and sets them onto a target object's matching properties. It collects any problems in a BindingResult instead of throwing.

open as a page

What is Spring's MessageSource, and how do you use getMessage to resolve a localized message with arguments?

level: juniorimportance: must knowfreq 55%

basics

~20 s

MessageSource is Spring's interface for resolving text by a code for a given Locale. You call getMessage(code, args, locale); args fill placeholders like {0} in the properties file, so one code renders in different languages.

open as a page

What is Spring's Resource interface, and what are its common implementations?

level: juniorimportance: must knowfreq 55%

basics

~10 s

Resource is Spring's abstraction for a readable low-level resource (a file, classpath entry, or URL). Common implementations are ClassPathResource, FileSystemResource, and UrlResource. You mainly call getInputStream(), exists(), and getFilename().

open as a page

How does @Validated enable method-level validation on Spring beans, and what makes it work?

level: middleimportance: must knowfreq 65%

basics

~20 s

Put @Validated on a bean's class; then constraint annotations on its method parameters (like @NotNull) and return values are enforced on every call. A MethodValidationPostProcessor creates an AOP proxy that checks them and throws ConstraintViolationException on failure.

open as a page

Compare Converter, ConverterFactory, and GenericConverter. When would you choose each?

level: middleimportance: must knowfreq 50%

basics

~20 s

Converter<S,T> converts one source type to one target type. ConverterFactory<S,R> converts one source to a whole family of subtypes (e.g. String→any Enum). GenericConverter is the most powerful: it can handle multiple type pairs and see field context/annotations.

open as a page

How does ResourceLoader interpret location prefixes like classpath:, file:, and http:?

level: middleimportance: must knowfreq 60%

basics

~20 s

ResourceLoader.getResource(location) turns a string into a Resource. A classpath: prefix gives a ClassPathResource, file: and http: give a UrlResource, and a plain path with no prefix is interpreted by the specific loader (usually classpath in an ApplicationContext).

open as a page

What do setAllowedFields, setDisallowedFields and setRequiredFields do on a DataBinder, and why do they matter for security?

level: seniorimportance: must knowfreq 50%

basics

~10 s

setAllowedFields restricts which property names may be bound (an allow-list); setDisallowedFields blocks specific names; setRequiredFields marks names that must be present or a required error is recorded. Allow-lists prevent mass-assignment attacks.

open as a page

What is the difference between the classpath: and classpath*: prefixes, and when do you need classpath*:?

level: seniorimportance: must knowfreq 50%

basics

~20 s

classpath: resolves a single resource — the first match found by the classloader. classpath*: (with a star) finds ALL resources with that path across every classpath entry and JAR. Use classpath*: to aggregate the same-named file from multiple modules.

open as a page

How does the condition attribute on @EventListener work, and how do you filter or chain events?

level: middleimportance: should knowfreq 35%

basics

~10 s

@EventListener(condition = "...SpEL...") evaluates a SpEL expression against the event; the listener runs only if it returns true. You reference the event via #root.event or its payload fields via #propertyName / the special #root.args.

open as a page

What are payload events, and how does Spring handle a plain object published as an event?

level: middleimportance: should knowfreq 45%

basics

~10 s

A payload event is any plain object you publish without extending ApplicationEvent. Spring wraps it in a PayloadApplicationEvent<T> internally, but your @EventListener method just declares the payload type as its parameter.

open as a page

What is BeanWrapper/BeanWrapperImpl, and how does it handle nested, indexed and mapped property paths?

level: middleimportance: should knowfreq 45%

basics

~10 s

BeanWrapper is Spring's low-level API to get/set JavaBean properties by name via getters/setters. It understands dotted and indexed paths like 'address.city' or 'orders[0].id', and can auto-create missing intermediate objects.

open as a page

What does registerCustomEditor do on a DataBinder/BeanWrapper, and when would you use it?

level: middleimportance: should knowfreq 38%

basics

~20 s

registerCustomEditor registers a JavaBeans PropertyEditor that tells the binder how to turn a String into (and out of) a specific type — for example parsing a date format. It scopes conversion to that binder or property.

open as a page

Compare ResourceBundleMessageSource and ReloadableResourceBundleMessageSource. When would you choose one over the other?

level: middleimportance: should knowfreq 45%

basics

~10 s

ResourceBundleMessageSource wraps java.util.ResourceBundle and caches bundles for the JVM's life. ReloadableResourceBundleMessageSource loads via Spring Resources and can re-read files on a timer (cacheSeconds), so you can change messages without a restart.

open as a page

How do you obtain a ResourceLoader / ResourcePatternResolver inside a bean, and how does PathMatchingResourcePatternResolver fit in?

level: middleimportance: should knowfreq 40%

basics

~10 s

Just autowire ResourceLoader (or ResourcePatternResolver) — the ApplicationContext implements both, so Spring injects itself. For wildcard scanning use ResourcePatternResolver.getResources(), which is backed by PathMatchingResourcePatternResolver.

open as a page

How do you make Spring application events asynchronous, and what changes about error handling and ordering?

level: seniorimportance: should knowfreq 50%

basics

~10 s

Add @Async to the @EventListener method (with @EnableAsync), or give the ApplicationEventMulticaster a TaskExecutor. Then listeners run on background threads, publishEvent no longer blocks, and listener exceptions no longer reach the publisher.

open as a page

At a high level, what is @TransactionalEventListener and why would you use it instead of @EventListener?

level: seniorimportance: should knowfreq 55%

basics

~20 s

@TransactionalEventListener is a specialized @EventListener that runs a listener tied to a transaction's outcome — by default only after the transaction commits — so side effects happen only when the data actually persisted. A plain @EventListener runs immediately, before commit.

open as a page

How do you write a custom constraint with a ConstraintValidator, and how can it use Spring beans?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Create an annotation meta-annotated with @Constraint pointing at a class implementing ConstraintValidator<A, T>. Put the logic in isValid(). Because Spring's LocalValidatorFactoryBean creates validators as Spring beans, you can @Autowired dependencies like a repository into it.

open as a page

What are validation groups and how do you use them with Spring's @Validated?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Validation groups let you apply different subsets of constraints in different situations. You tag constraints with a group marker interface, then activate that group — with Spring you pass the group class to @Validated(MyGroup.class) — so only those constraints run.

open as a page

What is a Formatter, how does it differ from a Converter, and how do @DateTimeFormat/@NumberFormat plug in via AnnotationFormatterFactory?

level: seniorimportance: should knowfreq 45%

basics

~20 s

A Formatter converts between an object and its String form in a locale-aware way (print + parse). Unlike a Converter it is always String↔Object and Locale-sensitive. AnnotationFormatterFactory lets annotations like @DateTimeFormat drive which Formatter is used on a given field.

open as a page

Explain the legacy PropertyEditor mechanism, why it was superseded by the ConversionService/Formatter SPI, and how the two coexist.

level: seniorimportance: should knowfreq 30%

basics

~20 s

PropertyEditor is the old JavaBeans way to convert String↔Object via setAsText/getAsText. It's stateful, not thread-safe, and String-only, so one instance is needed per binding. Spring introduced the stateless, thread-safe ConversionService/Formatter SPI to replace it, but still supports registered editors for backward compatibility.

open as a page

How do BindingResult and the Errors interface represent binding and validation outcomes, and how do you read them?

level: seniorimportance: should knowfreq 42%

basics

~10 s

BindingResult (a sub-interface of Errors) is the container that holds everything that went wrong during binding and validation: global ObjectErrors and per-field FieldErrors. You query it with hasErrors(), getFieldErrors(), getFieldError(name) and rejectValue().

open as a page

In a Spring MVC web app, how is the Locale for a request determined, and what is the role of LocaleResolver?

level: seniorimportance: should knowfreq 40%

basics

~10 s

A LocaleResolver decides which Locale a request uses. Spring MVC's DispatcherServlet calls it, then MessageSource lookups and LocaleContextHolder use that Locale. The default is AcceptHeaderLocaleResolver, which reads the browser's Accept-Language header.

open as a page

What is MessageSourceResolvable, and how does it connect Spring's validation errors (FieldError/ObjectError) to MessageSource?

level: seniorimportance: should knowfreq 32%

basics

~20 s

MessageSourceResolvable is an object carrying candidate codes, arguments, and a default message. MessageSource tries the codes in order and returns the first that resolves. Validation errors (FieldError, ObjectError) implement it, so getMessage(error, locale) produces localized error text.

open as a page

When would you choose Spring application events over a direct method call, and what are their limits?

level: principalimportance: should knowfreq 40%

basics

~20 s

Use events to decouple modules in one JVM: the producer emits a fact and any number of consumers react, with no compile-time dependency. Limits: in-process only, not persisted or retried, synchronous by default, and no delivery guarantee across crashes.

open as a page

How do you assemble and register a custom ConversionService across the core container, Spring MVC, and Spring Boot, and what precedence/threading concerns matter?

level: principalimportance: should knowfreq 35%

basics

~20 s

Build a ConversionService (e.g. DefaultFormattingConversionService) and add your Converters/Formatters. For @Value, register it as the bean named 'conversionService'. In MVC, add formatters via WebMvcConfigurer#addFormatters. In Boot, just declare Converter/Formatter beans. Keep converters stateless because the service is shared across threads.

open as a page

What reliability and portability pitfalls arise with classpath*: wildcard scanning across exploded classes, standard JARs, and Spring Boot fat JARs?

level: principalimportance: should knowfreq 25%

basics

~20 s

Wildcard classpath*: scanning depends on the classloader enumerating JAR roots. Root-level wildcards can silently miss files in some servers and in Spring Boot's nested-JAR layout. Anchor patterns under a concrete package, avoid getFile(), and use getInputStream() so code works both exploded and packaged.

open as a page

How is Bean Validation wired in a Spring context, and what configuration/lifecycle pitfalls should you know as a principal engineer?

level: principalimportance: nice to knowfreq 25%

basics

~20 s

Spring Boot auto-registers a LocalValidatorFactoryBean (the injectable Validator) and a MethodValidationPostProcessor (for @Validated method validation). You can override them to customize the message source, constraint validator factory, or bootstrap options. Watch proxying, message interpolation, and validator statelessness.

open as a page

showing 1–30 of 32