Облегченный AOP без Spring без XML-конфигурации для добавления аннотаций к методам - PullRequest
0 голосов
/ 30 января 2019

Необходимо запускать методы до и после некоторых аннотаций.

Не используется spring, нет xml.Возможно ли иметь какой-то AOP-движок, который я установил из main (), чтобы он мог вызываться при необходимости?Также можно добавить метод для ручного вызова метода оценки.

Пример:

public void doThis(@RequiredSecurityRole("admin") user){
    doAOPStuff();
}

before() получить из БД и проверить, является ли пользователь администратором, выдает исключениеесли это не администратор.

after() войдите в базу данных и выполните действие.

Как этого добиться?

1 Ответ

0 голосов
/ 30 января 2019

Вы можете сделать это самостоятельно, используя класс java.lang.reflex.Proxy.Требуется, чтобы код, который вы используете, был определен в интерфейсе.

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

import java.lang.annotation.Retention;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DoItYourAop {

  public static void main(String[] args) {
    SaysHello saysHello = new SaysHelloImpl();
    InvocationHandler logger = new LoggingProxy(saysHello);
    SaysHello proxy = (SaysHello) Proxy.newProxyInstance(SaysHello.class.getClassLoader(),
        new Class[]{SaysHello.class}, logger);
    proxy.sayHello();
  }

  public interface SaysHello {

    void sayHello();

    void sayGoodbye();
  }

  public static class SaysHelloImpl implements SaysHello {
    @Log
    @Override
    public void sayHello() {
      System.out.println("Says Hello");
    }

    @Override
    public void sayGoodbye() {
      System.out.println("Says Goodbye");
    }
  }

  @Retention(RUNTIME)
  @interface Log {
  }

  public static class LoggingProxy implements InvocationHandler {

    private final Object proxied;

    public LoggingProxy(Object proxied) {
      this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      Method proxiedMethod = proxied.getClass().getMethod(method.getName(), method.getParameterTypes());
      boolean log = proxiedMethod.isAnnotationPresent(Log.class);
      if (log) {
        System.out.println("Before");
      }

      Object result = method.invoke(proxied, args);

      if (log) {
        System.out.println("After");
      }

      return result;
    }
  }
}
...