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:

  1. import io.micronaut.context.event.StartupEvent;
  2. import io.micronaut.runtime.event.annotation.EventListener;
  3. ...
  4. @EventListener
  5. void onStartup(StartupEvent event) {
  6. // startup logic here
  7. }

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:

  1. import io.micronaut.aop.Adapter;
  2. import io.micronaut.context.event.ApplicationEventListener;
  3. import io.micronaut.core.annotation.Indexed;
  4. import java.lang.annotation.*;
  5. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  6. @Documented
  7. @Retention(RUNTIME)
  8. @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
  9. @Adapter(ApplicationEventListener.class) (1)
  10. @Indexed(ApplicationEventListener.class)
  11. public @interface EventListener {
  12. }
1The @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.