5.3 Method Adapter Advice
There are sometimes cases where you want to introduce a new bean based on the presence of an annotation on a method. An example of this case is the @EventListener annotation which for each method annotated with @EventListener produces an implementation of ApplicationEventListener that invokes the annotated method.
For example the following snippet will run the logic contained within the method when the ApplicationContext starts up:
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.event.annotation.EventListener;
...
@EventListener
void onStartup(StartupEvent event) {
// startup logic here
}
The presence of the @EventListener annotation causes Micronaut to create a new class that implements the ApplicationEventListener and invokes the onStartup
method defined in the bean above.
The actual implementation of the @EventListener is trivial, it simply uses the @Adapter annotation to specify which SAM (single abstract method) type it adapts:
import io.micronaut.aop.Adapter;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.core.annotation.Indexed;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Documented
@Retention(RUNTIME)
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
@Adapter(ApplicationEventListener.class) (1)
@Indexed(ApplicationEventListener.class)
public @interface EventListener {
}
1 | The @Adapter annotation is used to indicate which SAM type to adapt. In this case ApplicationEventListener. |
Micronaut will also automatically align the generic types for the SAM interface if they are specified. |
Using this mechanism you can define custom annotations that use the @Adapter annotation and a SAM interface to automatically implement beans for you at compile time.