/* * Copyright (c) 2010-2016. Axon Framework * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.axonframework.eventhandling; import org.axonframework.messaging.Message; import org.axonframework.messaging.MetaData; import org.axonframework.messaging.annotation.MessageHandler; import org.axonframework.messaging.annotation.ParameterResolverFactory; import java.lang.annotation.*; /** * Annotation to be placed on methods that can handle events. The parameters of the annotated method are resolved using * parameter resolvers. * <p> * Axon provides a number of parameter resolvers that allow you to use the following parameter types:<ul> * <li>The first parameter is always the payload of the Event message</li> * <li>Parameters annotated with {@code @MetaDataValue} will resolve to the Meta Data value with the key as indicated * on the annotation. If required is false (default), null is passed when the meta data value is not present. If * required is true, the resolver will not match and prevent the method from being invoked when the meta data value is * not present.</li> * <li>Parameters of type {@link MetaData} will have the entire Meta Data of an Event Message * injected.</li> * <li>Parameters of type {@link java.time.Instant} (or any of its super classes or implemented interfaces) will * resolve to the timestamp of the EventMessage. This is the time at which the Event was generated.</li> * <li>Parameters assignable to {@link Message} will have the entire {@link * EventMessage} injected (if the message is assignable to that parameter). If the first * parameter is of type message, it effectively matches an Event of any type, even if generic parameters would suggest * otherwise. Due to type erasure, Axon cannot detect what parameter is expected. In such case, it is best to declare a * parameter of the payload type, followed by a parameter of type Message.</li> * <li>When using Spring and {@code <axon:annotation-config/>} is declared, any other parameters will * resolve to autowired beans, if exactly one autowire candidate is available in the application context. This allows * you to inject resources directly into {@code @EventHandler} annotated methods.</li> * </ul> * <p> * For each event, only a single method will be invoked per object instance with annotated methods. This method is * resolved in the following order: <ol> <li>First, the event handler methods of the actual class (at runtime) are * searched <li>If a method is found with a parameter that the domain event can be assigned to, it is marked as * eligible * <li>After a class has been evaluated (but before any super class), the most specific event handler method is * called. * That means that if an event handler for a class A and one for a class B are eligible, and B is a subclass of A, then * the method with a parameter of type B will be chosen<li>If no method is found in the actual class, its super class * is * evaluated. <li>If still no method is found, the event listener ignores the event </ol> * <p> * If you do not want any events to be ignored, but rather have some logging of the fact that an unhandled event came * by, make an abstract superclass that contains an event handler method that accepts any {@code Object}. * <p> * Note: if there are two event handler methods accepting the same argument, the behavior is undefined. * * @author Allard Buijze * @see AnnotationEventListenerAdapter * @see ParameterResolverFactory * @since 0.1 */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @MessageHandler(messageType = EventMessage.class) public @interface EventHandler { /** * The type of event this method handles. This handler will only be considered for invocation if the event message's * payload is assignable to this type. * <p> * Optional. If unspecified, the first parameter of the method defines the type of supported event. * * @return The type of the event this method handles. */ Class<?> payloadType() default Object.class; }