What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
CDI @Observes marks the event parameter of a synchronous observer method. In a JSF application, it receives a lifecycle-phase event only when the Faces implementation or an extension exposes that event and the observer uses the matching event type and qualifier; an ordinary CDI observer is not automatically a JSF phase listener.
How CDI @Observes works
Put @Observes on exactly one parameter of an observer method. CDI treats that parameter as the event payload. It selects observers by event-type assignability and qualifier matching; any other parameters are injection points.
import jakarta.enterprise.event.Observes;
public void onOrderChanged(@Observes OrderChanged event, AuditService audit) {
audit.record(event);
}
Here, CDI injects AuditService and passes the fired OrderChanged event to the method if the event type and qualifiers match.
Event types and qualifiers must match
The event type and its qualifiers form the observer contract. An observer with no qualifier matches an event with no qualifier. If an event carries a qualifier, an observer must declare the corresponding qualifier type, with matching values for members that are not marked @Nonbinding. A method that listens for a different type or qualifier will not receive that event.
How to observe a JSF lifecycle phase
CDI 4.1 no longer specifies integration with Jakarta EE, so it does not, by itself, define how a CDI observer receives JSF lifecycle notifications. That connection must be provided by the Faces implementation or an extension. The Jakarta Faces API includes CdiExtension, which observes CDI container lifecycle events; that fact alone does not make every JSF phase a CDI event.
For example, Apache MyFaces Extensions CDI documents a phase observer using its @AfterPhase qualifier and a PhaseEvent payload:
Rank #2
public void observePostInvokeApplication(
@Observes @AfterPhase(JsfPhaseId.INVOKE_APPLICATION) PhaseEvent event) {
// React after JSF invokes the application phase.
}
This example is specific to the extension that defines @AfterPhase and JsfPhaseId. Use the event type and qualifier supplied by the Faces integration in your application, and check that integration’s documentation for the version in use. A plain observer for a CDI application event does not automatically observe JSF phases.
Choosing between CDI and JSF event approaches
| Approach | Event payload and selection | Lifecycle coverage | Delivery and transaction behavior | Portability and testing |
|---|---|---|---|---|
CDI @Observes |
Your application event type; CDI matches assignable types and qualifiers. | Application events only unless an integration explicitly exposes JSF phases. | Synchronous by default; supports transaction-phase and reception controls. | CDI event semantics apply, but JSF integration does not follow from this observer alone. The observer bean can be tested by firing its event through CDI. |
| Faces integration or extension phase observer | The integration’s phase-event type and qualifier, such as the documented PhaseEvent and @AfterPhase example. |
Only the JSF phases exposed by that integration. | Follow the integration’s delivery contract; do not assume CDI transaction controls apply to a phase notification. | Specific event and qualifier APIs vary by integration and version. Test against the Faces implementation and extension used by the application. |
CDI @ObservesAsync |
A CDI event type selected through CDI event matching. | Asynchronous CDI event notification; it does not itself expose JSF phases. | Asynchronous; asynchronous observers cannot be transactional. | Useful when asynchronous CDI notification is intended, not as a replacement for a Faces phase integration. |
For a JSF-specific reaction, first identify which integration emits the phase notification and what phase vocabulary it exposes. For application-domain notifications, use a CDI event with an explicit payload and qualifiers. Choose asynchronous delivery only when deferred notification is suitable for the work; it is not interchangeable with a synchronous callback in the request lifecycle.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Control when and whether a CDI observer runs
Transaction phase
For a synchronous observer, @Observes(during=...) selects a transaction phase. The default is IN_PROGRESS; the available phases are BEFORE_COMPLETION, AFTER_SUCCESS, AFTER_FAILURE, and AFTER_COMPLETION. Use a transaction phase when the observer’s work must be aligned with the outcome of the event’s transaction, rather than assuming every observer runs after a successful commit.
Reception of an existing contextual instance
notifyObserver=IF_EXISTS makes notification conditional on an already-existing contextual instance. It controls whether CDI delivers to such an instance; it is not a way to create an instance just to receive the event.
Rank #4
Asynchronous notification
@ObservesAsync marks an asynchronous observer parameter instead of @Observes. Use it for asynchronous CDI events, not for a JSF phase callback that must participate in the current lifecycle. Asynchronous observers cannot use transactional observer delivery.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

