5.3 Method Adapter Advice

There are cases where you want to introduce a new bean based on the presence of an annotation on a method. An example of this is the @EventListener annotation which produces an implementation of ApplicationEventListener for each annotated method that invokes the annotated method.

For example the following snippet runs 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 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. @Inherited
  12. public @interface EventListener {
  13. }
1The @Adapter annotation indicates which SAM type to adapt, in this case ApplicationEventListener.
Micronaut also automatically aligns 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.