2015-04-27 4 views
0

Мне интересно, могу ли я использовать пользовательскую аннотацию для вызова некоторого метода сразу после аннотированного. Например, у меня есть класс, который содержит некоторые параметры, которые также могут уведомлять объекты, которые что-то изменилось (например, пользователь изменил что-то на панели настроек). Не все слушатели интересуются всеми типами событий, поэтому MyEvent - это перечисление. Теперь у меня есть структура, как это:Могу ли я использовать аннотацию для вызова метода после аннотированного?

class Settings 
{ 
    private ArrayList<Listeners> listeners; 

    private void notifyListeners(MyEvent e) 
    { 
     // notify all listeners that something was changed 
    } 

    public void setSomeOption(int value) 
    { 
     // validate parameter, store it etc. 
     notifyListeners(MyEvent.SOME_INTEGER_SETTING_CHANGED); 
    } 
} 

Конечно объект прослушивания должен проверить тип события и игнорировать его или выполнять какие-то действия, но это не тот случай.

Я интересно, если я могу добиться этого с аннотациями, как этот

@NotifyAnnotation(MyEvent.SOME_INTEGER_SETTING_CHANGED) 
public void setSomeOption(int value) 
{ 
    // validate parameter, store it etc. 
    // NO NEED TO CALL NOTIFY HERE - WILL BE HANDLED BY ANNOTATION 
} 

В JUnit, например, мы имеем @Before или @After аннотаций, и мне интересно, если JUnit имеет собственные аннотации анализатор, который обрабатывает метод аннотированным таким образом, или подобное поведение может быть сделано проще, поскольку аннотации могут быть @Retention(value=RUNTIME).

Я знаю, что в этом примере это может выглядеть чрезмерно сложным, и вызов notifyListeners() очень симпатичен, но я не знаю, можно ли использовать аннотацию так, как я описал, и если да, могу ли я получить несколько советов? Я не ожидаю готового решения, просто намек, если это возможно, и что я должен принять во внимание.

+0

Этот (вид) звучит как использование аспектов. Это то, о чем вы говорите? – Stultuske

+0

@Stultuske Я не очень разбираюсь в аспектах, я только о них читаю в весенней документации. – Kuba

+0

Вы можете настроить «каждый метод с именем, как xxx, будет превзойден - сразу после него следует функциональность X». Все зависит от того, как вы его настраиваете. – Stultuske

ответ

1

Да, вы можете это сделать, но вам нужно использовать каркас или написать один самостоятельно. вы можете использовать, например, весенние аспекты и @After advice (или любой другой прокси-механизм). вы также можете использовать для этого полный aspectj. другой вариант - написать его самостоятельно, используя отражение api. в последнем случае вам понадобится некоторая инверсия управления - какой-то механизм, который запустит ваш метод, а затем другой метод.

1

В аннотациях вам нужен класс, который проверяет его. они не работают на себя. Способы проверки системы с отражением.

Annotation<NotifyAnnotation> a = method.getAnnotation(); 

И явно вызывать их методы

a.notifyListeners(a.evt); 

Я не вижу никаких преимуществ с вашим делом. но я вижу полные недостатки. Они не должны использоваться в реальном кодировании только для тестовых систем или подобных сценариев, где внешняя система имеет контроль над вашим классом.

+0

Спасибо за ваш ответ, поэтому в этом случае мне пришлось бы получить аннотированные методы с отражением, а затем вызвать мой метод «уведомлять» с параметром, который я получу из аннотации, не так ли? – Kuba

0

Это может быть сделано с использованием манипуляции с байт-кодом (JAssist, Asm, Java Rocks ...). Все классы будут созданы экземпляром Factory, который будет идентифицировать аннотированные методы и в первой строке этого метода будет вызывать вызов метода, указанного в его аннотации.

Смежные вопросы