MethodInterceptor Example

    MethodInterceptor Example

    1. import io.micronaut.aop.MethodInterceptor
    2. import io.micronaut.aop.MethodInvocationContext
    3. import io.micronaut.core.type.MutableArgumentValue
    4. import javax.inject.Singleton
    5. @Singleton
    6. class NotNullInterceptor implements MethodInterceptor<Object, Object> { (1)
    7. @Override
    8. Object intercept(MethodInvocationContext<Object, Object> context) {
    9. Optional<Map.Entry<String, MutableArgumentValue<?>>> nullParam = context.getParameters()
    10. .entrySet()
    11. .stream()
    12. .filter({entry ->
    13. MutableArgumentValue<?> argumentValue = entry.getValue()
    14. return Objects.isNull(argumentValue.getValue())
    15. })
    16. .findFirst() (2)
    17. if (nullParam.isPresent()) {
    18. throw new IllegalArgumentException("Null parameter [" + nullParam.get().getKey() + "] not allowed") (3)
    19. } else {
    20. return context.proceed() (4)
    21. }
    22. }
    23. }

    MethodInterceptor Example

    1. import io.micronaut.aop.MethodInterceptor
    2. import io.micronaut.aop.MethodInvocationContext
    3. import io.micronaut.core.type.MutableArgumentValue
    4. import javax.inject.Singleton
    5. import java.util.Objects
    6. import java.util.Optional
    7. @Singleton
    8. class NotNullInterceptor : MethodInterceptor<Any, Any> { (1)
    9. override fun intercept(context: MethodInvocationContext<Any, Any>): Any {
    10. val nullParam = context.parameters
    11. .entries
    12. .stream()
    13. .filter { entry ->
    14. val argumentValue = entry.value
    15. Objects.isNull(argumentValue.value)
    16. }
    17. return if (nullParam.isPresent) {
    18. throw IllegalArgumentException("Null parameter [" + nullParam.get().key + "] not allowed") (3)
    19. } else {
    20. }
    21. }
    22. }

    To put the new MethodInterceptor to work the next step is to define an annotation that will trigger the MethodInterceptor:

    1. import io.micronaut.context.annotation.Type;
    2. import io.micronaut.aop.Around;
    3. import java.lang.annotation.*;
    4. import static java.lang.annotation.RetentionPolicy.RUNTIME;
    5. @Documented
    6. @Retention(RUNTIME) (1)
    7. @Target({ElementType.TYPE, ElementType.METHOD}) (2)
    8. @Around (3)
    9. @Type(NotNullInterceptor.class) (4)
    10. public @interface NotNull {
    11. }

    Around Advice Annotation Example

    Around Advice Annotation Example

    1. import io.micronaut.aop.Around
    2. import io.micronaut.context.annotation.Type
    3. import java.lang.annotation.Documented
    4. import java.lang.annotation.Retention
    5. import java.lang.annotation.RetentionPolicy.RUNTIME
    6. @Documented
    7. @Retention(RUNTIME) (1)
    8. @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) (2)
    9. @Around (3)
    10. @Type(NotNullInterceptor::class) (4)
    11. annotation class NotNull

    With the interceptor and annotation implemented you can then simply apply the annotation to the target classes:

    Around Advice Usage Example

    1. @Singleton
    2. public class NotNullExample {
    3. @NotNull
    4. void doWork(String taskName) {
    5. System.out.println("Doing job: " + taskName);
    6. }
    7. }
    1. @Singleton
    2. class NotNullExample {
    3. @NotNull
    4. void doWork(String taskName) {
    5. println("Doing job: " + taskName)
    6. }
    7. }

    Around Advice Usage Example

    Whenever the type NotNullExample is injected into any class, a compile time generated proxy will instead be injected that decorates the appropriate method calls with the @NotNull advice defined earlier. You can verify that the advice works by writing a test. The following test uses a JUnit ExpectedException rule to verify the appropriate exception is thrown when an argument is null:

    Around Advice Test

    1. @Rule
    2. public ExpectedException thrown = ExpectedException.none();
    3. @Test
    4. public void testNotNull() {
    5. try (ApplicationContext applicationContext = ApplicationContext.run()) {
    6. NotNullExample exampleBean = applicationContext.getBean(NotNullExample.class);
    7. thrown.expect(IllegalArgumentException.class);
    8. thrown.expectMessage("Null parameter [taskName] not allowed");
    9. exampleBean.doWork(null);
    10. }
    11. }

    Around Advice Test

    1. void "test not null"() {
    2. when:
    3. ApplicationContext applicationContext = ApplicationContext.run()
    4. NotNullExample exampleBean = applicationContext.getBean(NotNullExample.class)
    5. exampleBean.doWork(null)
    6. then:
    7. IllegalArgumentException ex = thrown()
    8. ex.message == 'Null parameter [taskName] not allowed'
    9. cleanup:
    10. applicationContext.close()
    11. }
    1. @Test
    2. fun testNotNull() {
    3. val applicationContext = ApplicationContext.run()
    4. val exampleBean = applicationContext.getBean(NotNullExample::class.java)
    5. val exception = shouldThrow<IllegalArgumentException> {
    6. exampleBean.doWork(null)
    7. }
    8. exception.message shouldBe "Null parameter [taskName] not allowed"
    9. applicationContext.close()
    10. }