Event Listener Generator

Describe an event's fields once -- get the AbstractEvent class, its AbstractEventListener subclass, the Spring bean wiring it up, and an example of publishing it.

🔒 Your code never leaves your browser — everything is generated locally from templates, no AI, no server round-trip.

  • Event name is required.
  • Listener name is required.
Becomes OrderStatusChangedEvent.java.
Becomes OrderStatusChangedListener.java -- can differ from the event name if several listeners react to the same event.

Event fields

trainingcore/src/com/prospect2p/core/events/OrderStatusChangedEvent.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.prospect2p.core.events;

import de.hybris.platform.servicelayer.event.events.AbstractEvent;

public class OrderStatusChangedEvent extends AbstractEvent
{
    private final java.lang.String orderCode;

    public OrderStatusChangedEvent(final java.lang.String orderCode)
    {
        this.orderCode = orderCode;
    }

    public java.lang.String getOrderCode()
    {
        return orderCode;
    }
}
Generated scaffold. Review and test before using in production.
Advertisement

What is an Event Listener in SAP Commerce?

SAP Commerce (Hybris) has a lightweight, in-process publish/subscribe mechanism built on EventService: application code publishes a POJO event (extending AbstractEvent), and any Spring bean registered as an AbstractEventListener<T> for that event type gets its onEvent() called synchronously by the publishing thread.

It's intentionally simple -- no message broker, no persistence, no retry -- which makes it the right tool for same-process notifications (kick off a process, invalidate a cache, write an audit log) and the wrong tool for anything that needs guaranteed delivery or to survive a restart.

When to use it

Use an event + listener to decouple "something happened" from "here's what to do about it" -- e.g. publish an OrderPlacedEvent from checkout code, and let one or more listeners react (send a confirmation email, update analytics, trigger a warehouse process) without checkout code knowing about any of them.

If the reaction needs to run on a schedule rather than in response to something happening, use a CronJob instead. If it needs to pause and resume over a long period, start a Business Process from the listener rather than doing the work directly in onEvent().

Files generated

  • The event class (<Name>Event.java) extending AbstractEvent, with a field, constructor, and getter per event field.
  • The listener class (<Name>Listener.java) extending AbstractEventListener<Event> with onEvent() overridden.
  • A Spring bean registering the listener with parent="abstractEventListener".
  • A small usage-example class showing eventService.publishEvent(new <Name>Event(...)).

Step-by-step: how to use the output

  1. Copy the event and listener Java classes into <extension>/src/<package>/events/, and merge the Spring bean into your extension's -spring.xml.
  2. Replace the TODO in onEvent() with the listener's real work, using the event's getters for each field.
  3. Publish the event from the code path that should trigger it -- inject EventService (Spring-wired, not constructed directly like the usage example) and call publishEvent(new <Name>Event(...)).
  4. If cluster-aware delivery was requested, implement ClusterAwareEvent's method once you've confirmed its exact signature for the installed platform version -- the generated TODO marks where.

Common mistakes

  • Assuming publishEvent() is asynchronous -- by default listeners run synchronously on the publishing thread, so slow work in onEvent() slows down whatever published the event.
  • Checking "cluster-aware" without actually implementing ClusterAwareEvent's method -- just adding the interface does nothing by itself, and this generator deliberately leaves that method as a TODO rather than guess its signature.
  • Giving the event mutable fields -- events are meant to be an immutable snapshot of what happened, which is why every field here is final and set only via the constructor.
  • Doing long-running or transactional work directly in onEvent() instead of starting a CronJob or Business Process for it -- an event listener is for quick reactions, not for orchestrating multi-step work.

Frequently asked questions

Is EventService delivery synchronous or asynchronous?

Synchronous by default -- publishEvent() calls every matching listener's onEvent() on the calling thread before returning. Some projects configure an asynchronous event multicaster for specific event types, but that's an explicit Spring configuration choice, not the default.

What does AbstractEventListener<T> actually do for me?

It handles the type filtering -- onEvent(AbstractEvent) from the Spring event system checks whether the incoming event is an instance of T before delegating to your typed, protected onEvent(T event) method, so you never need an instanceof check yourself.

When should I implement ClusterAwareEvent?

When the event needs to be handled on every node of a cluster, not just the node that published it (e.g. invalidating a local cache everywhere). This generator adds the implements clause when requested but leaves the required method as a verify-and-implement TODO, since its exact signature has shifted across SAP Commerce versions.

Can one event have multiple listeners?

Yes -- register as many AbstractEventListener<T> beans for the same event type as needed; EventService calls all of them. There's no guaranteed ordering between listeners unless you add your own coordination.

Why are the event's fields final with no setters?

An event should represent an immutable fact about something that already happened. If a listener needs to react differently based on some field, it should read it via a getter -- not mutate the event, which other listeners may still be reading.

🗳️ Vote for the next SAP Commerce guide

Vote or suggest a topic
What should we write next? Vote