Вызовите метод, прежде чем аннотировать другой - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь добавить функциональность в сигнатуру метода интерфейса с помощью аннотаций.

идея состоит в том, чтобы вызывать некоторые другие методы для каждого аннотированного.

например, если у меня есть подпись этого метода:

public interface IMyInterface{

    @Entity(visibileName = "Name")
    public TextField getName();
}

Мне нужно вызвать метод, который печатает имя строки до, после этого метода. также, если есть какой-либо способ определить функциональность этого метода во время выполнения.

Я также открыт для структурных изменений.

1 Ответ

1 голос
/ 12 марта 2019

Если вы хотите аннотировать interface методов, чем , то возможно без AOP.
Просто используйте Динамические прокси !

База interface для реализации прокси - это InvocationHandler

InvocationHandler - это интерфейс, реализованный обработчиком вызовов экземпляра прокси.


Следуйте комментариям в коде.

static class MyInterfaceProxy implements InvocationHandler {
    private static final Map<String, Method> METHODS = new HashMap<>(16);

    static {
        // Scan each interface method for the specific annotation
        // and save each compatible method
        for (final Method m : IMyInterface.class.getDeclaredMethods()) {
            if (m.getAnnotation(YourAnnotation.class) != null) {
                METHODS.put(m.getName(), m);
            }
        }
    }

    private final IMyInterface toBeProxied;

    private MyInterfaceProxy(final IMyInterface toBeProxied) {
        // Accept the real implementation to be proxied
        this.toBeProxied = toBeProxied;
    }

    @Override
    public Object invoke(
            final Object proxy,
            final Method method,
            final Object[] args) throws InvocationTargetException, IllegalAccessException {
        // A method on MyInterface has been called!
        // Check if we need to call it directly or if we need to
        // execute something else before!
        final Method found = METHODS.get(method.getName());

        if (found != null) {
            // The method exist in our to-be-proxied list
            // Execute something and the call it
            // ... some other things
            System.out.println("Something else");
        }

        // Invoke original method
        return method.invoke(toBeProxied, args);
    }
}

Чтобы использовать эту реализацию InvocationHandler, вам нужен реальный экземпляр объекта для прокси.

Допустим, у вас есть Factory для MyInterface.реализации

MyInterface getMyInsterface() {
   ...
   final MyInterface instance = ...

   // Create the proxy and inject the real implementation
   final IMyInterface proxy = (IMyInterface) Proxy.newProxyInstance(
        MyInterfaceProxy.class.getClassLoader(),
        new Class[] {IMyInterface.class},
        new MyInterfaceProxy(instance) // Inject the real instance
    );

   // Return the proxy!
   return proxy;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...