Как выполнить что-то для каждого вызова метода с комментариями? - PullRequest
0 голосов
/ 12 июня 2019

Я хочу написать аннотацию на Java, которая выполняет что-то до и после выполнения аннотированного метода, аналогично тому, что можно сделать в Spring с аспектами.

Я уже пробовал аспект Spring, но он работает только для Beans (, как этот парень упомянул ), и я хочу остаться независимым от среды Spring.

Простой класс, который записывает строку в консоль:

public class Main {
    public static void main(String[] args) {
        say("How are you?");
    }

    @Hello
    private static void say(String s) {
        System.out.println(s);
    }
}

Связанная аннотация:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Hello {}

А мне нужно что-то вроде (выводится из аспекта Spring)

public Object process(ProceedingJoinPoint proceedingJoinPoint) {
    System.out.println("Hello");
    Object proceed = null;
    try {
        proceed = proceedingJoinPoint.proceed();
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }
    System.out.println("world!");
    return proceed;
}

Я хочу следующий вывод:

Hello

Как дела?

мир!

Edit:

Я создал следующий аспект (без аннотаций), но он не работает

@lombok.extern.java.Log
public aspect Log {
    pointcut methodExecuted():execution(* **(..));

    void around(): methodExecuted() {
        log.info("Hello");
        proceed();
        log.info("world!");
    }
}

Где моя ошибка?

1 Ответ

1 голос
/ 13 июня 2019

Предполагая, что вы успешно скомпилировали свой аспект с помощью компилятора AspectJ, он должен работать с кодом, который вы использовали, только чтобы он регистрировал все выполнения метода, т. Е. Также main(..), поэтому вы должны дважды просматривать выходные данные аспекта до и после "Как твои дела?". Если вы ничего не видите, возможно, вы допустили ошибку при настройке системы сборки.

Вы должны изменить pointcut, чтобы фактически ограничить ведение журнала аннотированными методами: execution(* *(..)) && @annotation(Hello). Более того, если ваш совет имеет тип возврата void, регистрация не будет работать с не пустыми методами. Поэтому вы должны использовать тип возврата Object и фактически возвращать результат proceed().

Я также настоятельно призываю вас не только слепо владеть таким мощным инструментом, как AspectJ, но и изучить некоторую документацию, прежде чем вы это сделаете. Совершенно очевидно, что вы не сделали этого или только очень бегло. Тогда вы получите эффект не слишком способного пользователя с инструментом. ; -)

Вот мой MCVE :

package de.scrum_master.app;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(METHOD)
public @interface Hello {}
package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    say("How are you?");
  }

  @Hello
  private static void say(String s) {
    System.out.println(s);
  }
}
package de.scrum_master.aspect;

import de.scrum_master.app.Hello;

public aspect LoggingAspect {
  pointcut methodExecuted() : execution(* *(..)) && @annotation(Hello);

  Object around(): methodExecuted() {
    System.out.println("Hello");
    Object result = proceed();
    System.out.println("world!");
    return result;
  }
}

Журнал консоли:

Hello
How are you?
world!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...