迟到了游戏,但我将其提供给以后可能会偶然发现此问题的开发人员。
如果您的应用程序依赖 AOP 才能正常运行,我强烈建议您不要使用AOP 。方面的工作方式如下:
- 建议(其他行为)适用于
- 连接点(可以附加附加代码的地方,例如方法的开始或结束,或触发给定事件的地方)
- ... 切入点(检测给定连接点是否匹配的模式)的模式匹配
对于长时间从事计算机工作的人来说,使用模式这一事实可能需要仔细观察。因此,这里有一个切入点的示例,该切入点与任何命名方法set
都匹配,而与参数无关:
call(* set(..))
因此,这是一个相当广泛的切入点,并且应该清楚地建议您谨慎处理此问题(无双关语),因为您将建议应用于许多事物。
不管怎么说,让我们为所有内容提供建议,无论名称或签名如何!
execution(* *(..))
因此很明显,我们应该谨慎,因为这里有很多功能,但这并不是针对方面的论点-这是要谨慎的论点,因为这里有很多功能,而且模式匹配很容易出错(只要按您喜欢的搜索引擎臭虫,玩得开心)。
所以这看起来是一个相对安全的切入点:
pointcut setter(): target(Point) &&
( call(void setX(int)) ||
call(void setY(int)) );
如果找到命名方法setX
或对象setY
上的方法,则可以明确地提供建议Point
。这些方法只能接收int
,并且必须为void
。看起来很安全,对不对?好吧,如果这些方法存在并且您已应用正确的建议,那将是安全的。如果不是,那就太糟了;它默默地失败了。
举个例子,一个朋友正在尝试调试Java应用程序,每个人在很长一段时间内都会返回错误的数据。这是一次罕见的失败,并且似乎与任何特定事件或特定数据都不相关。这是一个线程错误,非常难以测试或检测。事实证明,他们使用方面来锁定方法并使它们“线程安全”,但是程序员重命名了一种方法,并且切入点未能匹配该方法,从而导致应用程序无提示损坏。
因此,我告诉人们,如果他们必须使用AOP来对待诸如异常之类的方面:在设计良好的系统中,如果没有任何问题,可以将其删除,并且软件仍然可以正常运行。但是,如果程序的功能取决于AOP,则会在程序中引入不必要的脆弱性。
因此,日志记录,调试和跟踪是完美的方面行为示例,但是安全性高吗?不。线程安全?不。
有关AOP的替代方案,请参见traits。它们不是直接固定在语言上,而是直接集成到语言中,不需要“特征感知” IDE(尽管它可以提供帮助),并且如果不存在所需的方法,则编译时会失败。特质在处理关注点分离方面做得更加干净,因为从一开始就更好地定义了问题。我广泛使用它们,它们很棒。