or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

annotation-config.mdaot.mdcaching.mdcontext-lifecycle.mdevents.mdformatting.mdi18n.mdindex.mdjmx.mdresilience.mdscheduling.mdstereotypes.mdvalidation.md
tile.json

events.mddocs/

Event System

@EventListener

@Component
public class UserEventHandler {

    @EventListener
    public void handleUserCreated(UserCreatedEvent event) {
        // Handle event
    }

    @EventListener(condition = "#event.username == 'admin'")
    public void handleAdminCreated(UserCreatedEvent event) {
        // Conditional handling using SpEL
    }

    @EventListener
    @Order(1)
    public void firstHandler(OrderEvent event) {}

    @EventListener
    @Order(2)
    public void secondHandler(OrderEvent event) {}

    @EventListener
    @Async
    public void asyncHandler(AsyncEvent event) {
        // Async processing
    }

    @EventListener
    @Transactional
    public void transactionalHandler(Event event) {
        // Participates in transaction
    }
}

Publishing Events

@Service
public class UserService {

    @Autowired
    private ApplicationEventPublisher publisher;

    public void createUser(User user) {
        // Save user
        publisher.publishEvent(new UserCreatedEvent(user));
    }

    // Spring 4.2+: Publish any object
    public void updateUser(User user) {
        publisher.publishEvent(user);  // User is the event
    }
}

Custom Events

public class UserCreatedEvent extends ApplicationEvent {

    private final User user;

    public UserCreatedEvent(Object source, User user) {
        super(source);
        this.user = user;
    }

    public User getUser() {
        return user;
    }
}

// Or POJO event (Spring 4.2+)
public class OrderPlacedEvent {
    private final Order order;
    private final LocalDateTime timestamp;

    public OrderPlacedEvent(Order order) {
        this.order = order;
        this.timestamp = LocalDateTime.now();
    }
    // Getters
}

Generic Events

public class EntityEvent<T> extends ApplicationEvent {
    private final T entity;

    public EntityEvent(Object source, T entity) {
        super(source);
        this.entity = entity;
    }

    public T getEntity() {
        return entity;
    }
}

@Component
public class GenericEventHandler {

    @EventListener
    public void handleUserEvent(EntityEvent<User> event) {
        User user = event.getEntity();
    }

    @EventListener
    public void handleOrderEvent(EntityEvent<Order> event) {
        Order order = event.getEntity();
    }
}

@TransactionalEventListener

@Component
public class TransactionalHandlers {

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleAfterCommit(OrderEvent event) {
        // Execute after transaction commits successfully
    }

    @TransactionalEventListener(phase = TransactionPhase.AFTER_ROLLBACK)
    public void handleAfterRollback(OrderEvent event) {
        // Execute after transaction rolls back
    }

    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
    public void handleAfterCompletion(OrderEvent event) {
        // Execute after commit or rollback
    }

    @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
    public void handleBeforeCommit(OrderEvent event) {
        // Execute before commit (still in transaction)
    }
}

Event Multicasting

@Configuration
public class EventConfig {

    @Bean
    public ApplicationEventMulticaster applicationEventMulticaster() {
        SimpleApplicationEventMulticaster multicaster =
            new SimpleApplicationEventMulticaster();

        // Async event publishing
        multicaster.setTaskExecutor(asyncExecutor());

        // Error handler
        multicaster.setErrorHandler(t -> {
            logger.error("Event handling error", t);
        });

        return multicaster;
    }

    @Bean
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("event-");
        executor.initialize();
        return executor;
    }
}

ApplicationListener Interface

@Component
public class CustomListener implements ApplicationListener<CustomEvent> {

    @Override
    public void onApplicationEvent(CustomEvent event) {
        // Handle event
    }
}

// Generic listener
@Component
public class GenericListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof UserEvent) {
            // Handle user event
        } else if (event instanceof OrderEvent) {
            // Handle order event
        }
    }
}

// Smart listener for async/order control
@Component
public class SmartListener implements SmartApplicationListener {

    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return UserEvent.class.isAssignableFrom(eventType);
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        // Handle event
    }

    @Override
    public int getOrder() {
        return 10;  // Lower = higher priority
    }
}