2015-04-27 98 views
0

我想知道如果我可以使用自定义注释在注释之后调用某种方法。例如,我有一个类,其中包含一些设置,可以通知对象某些内容已经更改(例如,用户在设置面板中更改了某些内容)。并非所有的听众都对所有类型的事件感兴趣,所以MyEvent是enum。现在我有结构是这样的:注释后可以使用注释来调用方法吗?

当然
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我对方面并不是很熟悉,我只在Spring文档 – Kuba

+0

中阅读过有关它们的内容。您可以配置“每个方法的名称都像xxx一样 - 紧接着是X功能”。全部取决于你如何配置它。 – Stultuske

回答

1

是的,你可以做到这一点,但你必须使用框架或自己写一个框架。您可以使用例如弹簧方面和@After advice(或任何其他代理机制)。你也可以用这个完整的aspectj。另一种选择是使用反射API自己编写它。在最后一种情况下,你将需要某种反转控制 - 一些机制,将启动你的方法,然后另一种方法

1

在注释中,您需要一个类来检查它。他们不会自己工作。 系统检查它们的方式是反射。

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

,并明确调用它们的方法

a.notifyListeners(a.evt); 

我看不到你的情况下,任何的优势。但我看到充满缺点。它们不应该用于实际编码中,仅用于测试系统或类似场景,其中外部系统可以控制班级。

+0

感谢您的回答,所以在这种情况下,我将不得不使用反射来获取带注释的方法,然后使用参数I调用我的'notify'方法,我将从注释中获取,对吧? – Kuba

0

它可以做到这一点使用字节码操作(JAssist,Asm,Java Rocks ...)。所有类都将通过一个Factory来实例化,该Factory将识别带注释的方法,并在该方法的第一行中注入对其注释中指定的方法的调用。